*** empty log message ***
[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 // MappingInfo - This method collects mapping info 
21 // for the mapping from LLVM to machine code.
22 //
23 namespace {
24   class getMappingInfoForFunction : public Pass { 
25     std::ostream &Out;
26   private:
27     std::map<const Function*, unsigned> Fkey; //key of function to num
28     std::map<const MachineInstr*, unsigned> BBkey; //key basic block to num
29     std::map<const MachineInstr*, unsigned> MIkey; //key machine instruction to num
30     vector<vector<unsigned> > BBmap;
31     vector<vector<unsigned> > MImap;
32  
33     void createFunctionKey(Module &M);
34     void createBasicBlockKey(Module &M);    
35     void createMachineInstructionKey(Module &M);
36     void createBBToMImap(Module &M);
37     void createLLVMToMImap(Module &M);
38     unsigned writeNumber(unsigned X);
39     
40   public:
41     getMappingInfoForFunction(std::ostream &out) : Out(out){}
42
43     const char* getPassName() const {
44       return "Sparc CollectMappingInfoForInstruction";
45     }
46     
47     bool run(Module &M);
48   };
49 }
50
51
52 //pass definition
53 Pass *MappingInfoForFunction(std::ostream &out){
54   return (new getMappingInfoForFunction(out));
55 }
56
57 //function definitions :
58 //create and output maps to the .s file
59 bool getMappingInfoForFunction::run(Module &M) {
60
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   //unsigned r =0;
80   //for (Module::iterator FI = M.begin(), FE = M.end(); 
81   //FI != FE; ++FI){
82   //unsigned r = 0;
83   //  if(FI->isExternal()) continue;
84   //for (Function::iterator BI = FI->begin(), BE = FI->end(); 
85   // BI != BE; ++BI){
86   //r++;
87   //}
88   //Out <<"#BB in F: "<<r<<"\n";
89   //}
90   //Out <<"#BB: "<< r <<"\n";
91   //Out <<"BBkey.size() "<<BBkey.size()<<"\n";
92   //Out <<"BBmap.size() "<<BBmap.size()<<"\n";
93   // Write map to the sparc assembly stream
94   // Start by writing out the basic block to first and last
95   // machine instruction map to the .s file
96   Out << "\n\n!BB TO MI MAP\n";
97   Out << "\t.section \".data\"\n\t.align 8\n";
98   Out << "\t.global BBMIMap\n";
99   Out << "BBMIMap:\n";
100   //add stream object here that will contain info about the map
101   //add object to write this out to the .s file
102   //int x=0;
103   unsigned sizeBBmap=0;
104   unsigned sizeLImap=0;
105   for (vector<vector<unsigned> >::iterator BBmapI = 
106          BBmap.begin(), BBmapE = BBmap.end(); BBmapI != BBmapE;
107        ++BBmapI){
108     sizeBBmap += writeNumber((*BBmapI)[0]);
109     sizeBBmap += writeNumber((*BBmapI)[1]);
110     sizeBBmap += writeNumber((*BBmapI)[2]);
111     sizeBBmap += writeNumber((*BBmapI)[3]);
112     //x++;
113   }
114   //Out <<"sizeOutputed = "<<x<<"\n";
115   
116   Out << "\t.type BBMIMap,#object\n";
117   Out << "\t.size BBMIMap,"<<BBmap.size() << "\n";
118   
119   //output length info
120   Out <<"\n\n!LLVM BB MAP Length\n\t.section \".bbdata";
121   Out << "\",#alloc,#write\n\t.global BBMIMap_length\n\t.align 4\n\t.type BBMIMap_length,";
122   Out <<"#object\n\t.size BBMIMap_length,4\nBBMIMap_length:\n\t.word "
123       << sizeBBmap <<"\n\n\n\n";
124  
125
126   //Now write out the LLVM instruction to the corresponding
127   //machine instruction map
128   Out << "!LLVM I TO MI MAP\n";
129   Out << "\t.section\".data\"\n\t.align 8\n";
130   Out << "\t.global LMIMap\n";
131   Out << "LMIMap:\n";
132   //add stream object here that will contain info about the map
133   //add object to write this out to the .s file
134   for (vector<vector<unsigned> >::iterator MImapI = 
135          MImap.begin(), MImapE = MImap.end(); MImapI != MImapE;
136        ++MImapI){
137     sizeLImap += writeNumber((*MImapI)[0]);
138     sizeLImap += writeNumber((*MImapI)[1]);
139     sizeLImap += writeNumber((*MImapI)[2]);
140     sizeLImap += writeNumber((*MImapI)[3]);
141   }
142   Out << "\t.type LMIMap,#object\n";
143   Out << "\t.size LMIMap,"<<MImap.size() << "\n";
144   //output length info
145   Out <<"\n\n!LLVM MI MAP Length\n\t.section\".llvmdata";
146   Out << "\",#alloc,#write\n\t.global LMIMap_length\n\t.align 4\n\t.type LMIMap_length,";
147   Out <<"#object\n\t.size LMIMap_length,4\nLMIMap_length:\n\t.word "
148       << ((MImap.size())*4)<<"\n\n\n\n";
149
150   return false; 
151 }  
152
153 //write out information as .byte directives
154 unsigned getMappingInfoForFunction::writeNumber(unsigned X) {
155   unsigned i=0;
156   do {
157     unsigned tmp = X & 127;
158     X >>= 7;
159     if (X) tmp |= 128;
160     Out << "\t.byte " << tmp << "\n";
161     ++i;
162   } while(X);
163   return i;
164 }
165
166 //Assign a number to each Function 
167 void getMappingInfoForFunction::createFunctionKey(Module &M){
168   unsigned i = 0;
169   unsigned j = 0;
170   for (Module::iterator FI = M.begin(), FE = M.end();
171        FI != FE; ++FI){
172     //dont count F with 0 BBs
173     if(FI->isExternal()) continue;
174     Fkey[FI] = i;
175     ++i;
176   }
177 }
178      
179 //Assign a Number to each BB
180 void getMappingInfoForFunction::createBasicBlockKey(Module &M){
181   //unsigned i = 0;
182   for (Module::iterator FI = M.begin(), FE = M.end(); 
183        FI != FE; ++FI){
184     unsigned i = 0;
185     if(FI->isExternal()) continue;
186     for (Function::iterator BI = FI->begin(), BE = FI->end(); 
187          BI != BE; ++BI){
188       MachineCodeForBasicBlock &miBB = MachineCodeForBasicBlock::get(BI);
189       BBkey[miBB[0]] = i;
190       i = i+(miBB.size());
191     }
192   }
193 }
194
195 //Assign a number to each MI wrt beginning of the BB
196 void getMappingInfoForFunction::createMachineInstructionKey(Module &M){
197   for (Module::iterator FI = M.begin(), FE = M.end(); 
198        FI != FE; ++FI){
199     if(FI->isExternal()) continue;
200     for (Function::iterator BI=FI->begin(), BE=FI->end(); 
201          BI != BE; ++BI){
202       MachineCodeForBasicBlock &miBB = MachineCodeForBasicBlock::get(BI);
203       unsigned j = 0;
204       for (MachineCodeForBasicBlock::iterator miI = miBB.begin(),
205              miE = miBB.end(); miI != miE; ++miI, ++j){
206         MIkey[*miI] = j;
207       }
208     }
209   }
210 }
211
212 //BBtoMImap: contains F#, BB#, 
213 //              MI#[wrt beginning of F], #MI in BB
214 void getMappingInfoForFunction::createBBToMImap(Module &M){
215
216   for (Module::iterator FI = M.begin(), FE = M.end();
217        FI != FE; ++FI){ 
218     if(FI->isExternal())continue;
219     unsigned i = 0;
220     for (Function::iterator BI = FI->begin(), 
221            BE = FI->end(); BI != BE; ++BI){
222       MachineCodeForBasicBlock &miBB = MachineCodeForBasicBlock::get(BI);
223      //add record into the map
224       BBmap.push_back(vector<unsigned>());
225       vector<unsigned> &oneBB = BBmap.back();
226       oneBB.reserve(4);
227
228       //add F#
229       oneBB.push_back(Fkey[FI]);
230       //add BB#
231       oneBB.push_back( i );
232       //add the MI#[wrt the beginning of F]
233       oneBB.push_back( BBkey[ miBB[0] ]);
234       //add the # of MI
235       oneBB.push_back(miBB.size());
236       ++i;
237
238     }
239   }
240 }
241
242 //LLVMtoMImap: contains F#, BB#, LLVM#, 
243 //                           MIs[wrt to beginning of BB] 
244 void getMappingInfoForFunction::createLLVMToMImap(Module &M){
245   
246   for (Module::iterator FI = M.begin(), FE = M.end();
247        FI != FE; ++FI){
248     if(FI->isExternal()) continue;
249     unsigned i =0;
250     for (Function::iterator BI = FI->begin(),  BE = FI->end(); 
251          BI != BE; ++BI, ++i){
252       unsigned j = 0;
253       for (BasicBlock::iterator II = BI->begin(), 
254              IE = BI->end(); II != IE; ++II, ++j){
255         MachineCodeForInstruction& miI = 
256           MachineCodeForInstruction::get(II);
257         //do for each corr. MI
258         for (MachineCodeForInstruction::iterator miII = miI.begin(), 
259                miIE = miI.end(); miII != miIE; ++miII){
260
261           MImap.push_back(vector<unsigned>());
262           vector<unsigned> &oneMI = MImap.back();
263           oneMI.reserve(4);
264           
265           //add F#
266           oneMI.push_back(Fkey[FI]);
267           //add BB#
268           oneMI.push_back(i);
269           //add LLVM Instr#
270           oneMI.push_back(j);
271           //add MI#[wrt to beginning of BB]
272           oneMI.push_back(MIkey[*miII]);
273         }
274       }
275     } 
276   }
277 }
278
279