OSDN Git Service

radeonsi: initial WIP SI code
[android-x86/external-mesa.git] / src / gallium / drivers / radeon / AMDILLiteralManager.cpp
1 //===--- AMDILLiteralManager.cpp - AMDIL Literal Manager Pass --*- C++ -*--===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //==-----------------------------------------------------------------------===//
9
10 #define DEBUG_TYPE "literal_manager"
11
12 #include "AMDIL.h"
13
14 #include "AMDILAlgorithms.tpp"
15 #include "AMDILKernelManager.h"
16 #include "AMDILMachineFunctionInfo.h"
17 #include "AMDILSubtarget.h"
18 #include "AMDILTargetMachine.h"
19 #include "llvm/CodeGen/MachineFunctionPass.h"
20 #include "llvm/CodeGen/Passes.h"
21 #include "llvm/Support/Debug.h"
22 #include "llvm/Target/TargetMachine.h"
23
24 using namespace llvm;
25
26
27 // AMDIL Literal Manager traverses through all of the LOADCONST instructions and
28 // converts them from an immediate value to the literal index. The literal index
29 // is valid IL, but the immediate values are not. The Immediate values must be
30 // aggregated and declared for clarity and to reduce the number of literals that
31 // are used. It is also illegal to declare the same literal twice, so this keeps
32 // that from occuring.
33
34 namespace {
35   class AMDILLiteralManager : public MachineFunctionPass {
36   public:
37     static char ID;
38     AMDILLiteralManager(TargetMachine &tm AMDIL_OPT_LEVEL_DECL);
39     virtual const char *getPassName() const;
40
41     bool runOnMachineFunction(MachineFunction &MF);
42   private:
43     bool trackLiterals(MachineBasicBlock::iterator *bbb);
44     TargetMachine &TM;
45     const AMDILSubtarget *mSTM;
46     AMDILKernelManager *mKM;
47     AMDILMachineFunctionInfo *mMFI;
48     int32_t mLitIdx;
49     bool mChanged;
50   };
51   char AMDILLiteralManager::ID = 0;
52 }
53
54 namespace llvm {
55   FunctionPass *
56   createAMDILLiteralManager(TargetMachine &tm AMDIL_OPT_LEVEL_DECL) {
57     return new AMDILLiteralManager(tm AMDIL_OPT_LEVEL_VAR);
58   }
59   
60 }
61
62 AMDILLiteralManager::AMDILLiteralManager(TargetMachine &tm
63                                          AMDIL_OPT_LEVEL_DECL)
64   : MachineFunctionPass(ID),
65     TM(tm) {
66 }
67
68 bool AMDILLiteralManager::runOnMachineFunction(MachineFunction &MF) {
69   mChanged = false;
70   mMFI = MF.getInfo<AMDILMachineFunctionInfo>();
71   const AMDILTargetMachine *amdtm =
72     reinterpret_cast<const AMDILTargetMachine *>(&TM);
73   mSTM = dynamic_cast<const AMDILSubtarget *>(amdtm->getSubtargetImpl());
74   mKM = const_cast<AMDILKernelManager *>(mSTM->getKernelManager());
75   safeNestedForEach(MF.begin(), MF.end(), MF.begin()->begin(),
76       std::bind1st(std::mem_fun(&AMDILLiteralManager::trackLiterals), this));
77   return mChanged;
78 }
79
80 bool AMDILLiteralManager::trackLiterals(MachineBasicBlock::iterator *bbb) {
81   MachineInstr *MI = *bbb;
82   uint32_t Opcode = MI->getOpcode();
83   switch(Opcode) {
84   default:
85     return false;
86   case AMDIL::LOADCONST_i8:
87   case AMDIL::LOADCONST_i16:
88   case AMDIL::LOADCONST_i32:
89   case AMDIL::LOADCONST_i64:
90   case AMDIL::LOADCONST_f32:
91   case AMDIL::LOADCONST_f64:
92     break;
93   };
94   MachineOperand &dstOp = MI->getOperand(0);
95   MachineOperand &litOp = MI->getOperand(1);
96   if (!litOp.isImm() && !litOp.isFPImm()) {
97     return false;
98   }
99   if (!dstOp.isReg()) {
100     return false;
101   }
102   // Change the literal to the correct index for each literal that is found.
103   if (litOp.isImm()) {
104     int64_t immVal = litOp.getImm();
105     uint32_t idx = MI->getOpcode() == AMDIL::LOADCONST_i64 
106                      ? mMFI->addi64Literal(immVal)
107                      : mMFI->addi32Literal(static_cast<int>(immVal), Opcode);
108     litOp.ChangeToImmediate(idx);
109     return false;
110   } 
111
112   if (litOp.isFPImm()) {
113     const ConstantFP *fpVal = litOp.getFPImm();
114     uint32_t idx = MI->getOpcode() == AMDIL::LOADCONST_f64
115                      ? mMFI->addf64Literal(fpVal)
116                      : mMFI->addf32Literal(fpVal);
117     litOp.ChangeToImmediate(idx);
118     return false;
119   }
120
121   return false;
122 }
123
124 const char* AMDILLiteralManager::getPassName() const {
125     return "AMDIL Constant Propagation";
126 }
127
128