Now will profile all Basic Blocks
[oota-llvm.git] / lib / Target / SparcV9 / InstrSelection / MappingInfo.cpp
1 //===- MappingInfo.cpp - create LLVM info and output to .s file ---------===//
2 //
3 // Create Map from LLVM BB and Instructions and Machine Instructions
4 // and output the information as .byte directives to the .s file
5 // Currently Sparc specific but will be extended for others later
6 //
7 //===--------------------------------------------------------------------===//
8
9 #include "llvm/CodeGen/MappingInfo.h"
10 #include "llvm/Pass.h"
11 #include "llvm/Module.h"
12 #include "llvm/CodeGen/MachineInstr.h"
13 #include "llvm/CodeGen/MachineCodeForBasicBlock.h"
14 #include "llvm/CodeGen/MachineCodeForInstruction.h"
15 #include <map>
16 #include <vector>
17 using std::vector;
18
19
20
21 // MappingInfo - This method collects mapping info 
22 // for the mapping from LLVM to machine code.
23 //
24 namespace {
25   class getMappingInfoForFunction : public Pass { 
26     std::ostream &Out;
27   private:
28     std::map<const Function*, int> Fkey; //key of function to num
29     std::map<const MachineInstr*, int> BBkey; //key basic block to num
30     std::map<const MachineInstr*, int> MIkey; //key machine instruction to num
31     vector<vector<int> > BBmap;
32     vector<vector<int> > MImap;
33
34     void createFunctionKey(Module &M);
35     void createBasicBlockKey(Module &M);    
36     void createMachineInstructionKey(Module &M);
37     void createBBToMImap(Module &M);
38     void createLLVMToMImap(Module &M);
39     void writeNumber(int X);
40
41   public:
42     getMappingInfoForFunction(std::ostream &out) : Out(out){}
43
44     const char* getPassName() const {
45       return "Sparc CollectMappingInfoForInstruction";
46     }
47     
48     bool run(Module &M);
49   };
50 }
51
52
53 //pass definition
54 Pass *MappingInfoForFunction(std::ostream &out){
55   return (new getMappingInfoForFunction(out));
56 }
57
58 //function definitions :
59 //create and output maps to the .s file
60 bool getMappingInfoForFunction::run(Module &M) {
61   //  Module *M = &m;
62
63   //map for Function to Function number
64   createFunctionKey(M);
65       
66   //map for BB to LLVM instruction number
67   createBasicBlockKey(M);
68       
69   //map from Machine Instruction to Machine Instruction number
70   createMachineInstructionKey(M);
71       
72   //map of Basic Block to first Machine Instruction and number 
73   // of instructions go thro each function
74   createBBToMImap(M);
75   
76   //map of LLVM Instruction to Machine Instruction 
77   createLLVMToMImap(M);
78   
79   
80   // Write map to the sparc assembly stream
81   // Start by writing out the basic block to first and last
82   // machine instruction map to the .s file
83   Out << "\n\n!BB TO MI MAP\n";
84   Out << "\t.section \".data\"\n\t.align 8\n";
85   Out << "\t.global BBMIMap\n";
86   Out << "BBMIMap:\n";
87   //add stream object here that will contain info about the map
88   //add object to write this out to the .s file
89   for (vector<vector<int> >::iterator BBmapI = 
90          BBmap.begin(), BBmapE = BBmap.end(); BBmapI != BBmapE;
91        ++BBmapI){
92     writeNumber((*BBmapI)[0]);
93     writeNumber((*BBmapI)[1]);
94     writeNumber((*BBmapI)[2]);
95     writeNumber((*BBmapI)[3]);
96   }
97   
98   Out << "\t.type BBMIMap,#object\n";
99   Out << "\t.size BBMIMap,"<<BBmap.size() << "\n";
100   
101   //output length info
102   Out <<"\n\n!LLVM BB MAP Length\n\t.section \".bbdata";
103   Out << "\",#alloc,#write\n\t.global BBMIMap_length\n\t.align 4\n\t.type BBMIMap_length,";
104   Out <<"#object\n\t.size BBMIMap_length,4\nBBMIMap_length:\n\t.word "
105       << ((BBmap.size())*4)<<"\n\n\n\n";
106  
107
108   //Now write out the LLVM instruction to the corresponding
109   //machine instruction map
110   Out << "!LLVM I TO MI MAP\n";
111   Out << "\t.section\".data\"\n\t.align 8\n";
112   Out << "\t.global LMIMap\n";
113   Out << "LMIMap:\n";
114   //add stream object here that will contain info about the map
115   //add object to write this out to the .s file
116   for (vector<vector<int> >::iterator MImapI = 
117          MImap.begin(), MImapE = MImap.end(); MImapI != MImapE;
118        ++MImapI){
119     writeNumber((*MImapI)[0]);
120     writeNumber((*MImapI)[1]);
121     writeNumber((*MImapI)[2]);
122     writeNumber((*MImapI)[3]);
123   }
124   Out << "\t.type LMIMap,#object\n";
125   Out << "\t.size LMIMap,"<<MImap.size() << "\n";
126   //output length info
127   Out <<"\n\n!LLVM MI MAP Length\n\t.section\".llvmdata";
128   Out << "\",#alloc,#write\n\t.global LMIMap_length\n\t.align 4\n\t.type LMIMap_length,";
129   Out <<"#object\n\t.size LMIMap_length,4\nLMIMap_length:\n\t.word "
130       << ((MImap.size())*4)<<"\n\n\n\n";
131
132   return false; 
133 }  
134
135 //write out information as .byte directives
136 void getMappingInfoForFunction::writeNumber(int X) {
137   do {
138     int tmp = X & 127;
139     X >>= 7;
140     if (X) tmp |= 128;
141     Out << "\t.byte " << tmp << "\n";    
142   } while(X);
143 }
144
145 //Assign a number to each Function 
146 void getMappingInfoForFunction::createFunctionKey(Module &M){
147   int i = 0;
148   int j = 0;
149   for (Module::iterator FI = M.begin(), FE = M.end();
150        FI != FE; ++FI){
151     if(FI->size() <=1) continue;
152     Fkey[FI] = i;
153     ++i;
154   }
155 }
156      
157 //Assign a Number to each BB
158 void getMappingInfoForFunction::createBasicBlockKey(Module &M){
159   int i = 0;
160   for (Module::iterator FI = M.begin(), FE = M.end(); 
161        FI != FE; ++FI){
162     //  int i = 0;
163     //if(FI->size() <= 1) continue;
164     for (Function::iterator BI = FI->begin(), BE = FI->end(); 
165          BI != BE; ++BI){
166       MachineCodeForBasicBlock &miBB = MachineCodeForBasicBlock::get(BI);
167       BBkey[miBB[0]] = i;
168       i = i+(miBB.size());
169     }
170   }
171 }
172
173 void getMappingInfoForFunction::createMachineInstructionKey(Module &M){
174   for (Module::iterator FI = M.begin(), FE = M.end(); 
175        FI != FE; ++FI){
176     //if(FI->size() <= 1) continue;
177     for (Function::iterator BI=FI->begin(), BE=FI->end(); 
178          BI != BE; ++BI){
179       MachineCodeForBasicBlock &miBB = MachineCodeForBasicBlock::get(BI);
180       int j = 0;
181       for (MachineCodeForBasicBlock::iterator miI = miBB.begin(),
182              miE = miBB.end(); miI != miE; ++miI, ++j){
183         MIkey[*miI] = j;
184       }
185     }
186   }
187 }
188
189 void getMappingInfoForFunction::createBBToMImap(Module &M){
190   //go thro each function in the module
191   for (Module::iterator FI = M.begin(), FE = M.end();
192        FI != FE; ++FI){ 
193     //if(FI->size() <= 1)continue;
194     //go thro each basic block in that function 
195     int i = 0;
196     for (Function::iterator BI = FI->begin(), 
197            BE = FI->end(); BI != BE; ++BI){
198       //create a Map record
199       //get the corresponding machine instruction 
200       MachineCodeForBasicBlock &miBB = MachineCodeForBasicBlock::get(BI);
201       //add record into the map
202       BBmap.push_back(vector<int>());
203       vector<int> &oneBB = BBmap.back();
204       oneBB.reserve(4);
205
206       //add the function number
207       oneBB.push_back(Fkey[FI]);
208       //add the machine instruction number
209       oneBB.push_back( i );
210       oneBB.push_back( BBkey[ miBB[0] ]);
211       //add the number of instructions
212       oneBB.push_back(miBB.size());
213       ++i;
214
215     }
216   }
217 }
218
219 void getMappingInfoForFunction::createLLVMToMImap(Module &M){
220   
221   for (Module::iterator FI = M.begin(), FE = M.end();
222        FI != FE; ++FI){
223     //if(FI->size() <= 1) continue;
224     int i =0;
225     for (Function::iterator BI = FI->begin(),  BE = FI->end(); 
226          BI != BE; ++BI, ++i){
227       int j = 0;
228       for (BasicBlock::iterator II = BI->begin(), 
229              IE = BI->end(); II != IE; ++II, ++j){
230         MachineCodeForInstruction& miI = 
231           MachineCodeForInstruction::get(II);
232         for (MachineCodeForInstruction::iterator miII = miI.begin(), 
233                miIE = miI.end(); miII != miIE; ++miII){
234           
235           vector<int> oneMI;
236           oneMI.push_back(Fkey[FI]);
237           oneMI.push_back(i);
238           oneMI.push_back(j);
239           oneMI.push_back(MIkey[*miII]);
240           MImap.push_back(oneMI);
241         }
242       }
243     } 
244   }
245 }
246
247