added check for Function with 0 BB
[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*, int> Fkey; //key of function to num
28     std::map<const MachineInstr*, int> BBkey; //key basic block to num
29     std::map<const MachineInstr*, int> MIkey; //key machine instruction to num
30     vector<vector<int> > BBmap;
31     vector<vector<int> > 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     void writeNumber(int 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   //  Module *M = &m;
61
62   //map for Function to Function number
63   createFunctionKey(M);
64       
65   //map for BB to LLVM instruction number
66   createBasicBlockKey(M);
67       
68   //map from Machine Instruction to Machine Instruction number
69   createMachineInstructionKey(M);
70       
71   //map of Basic Block to first Machine Instruction and number 
72   // of instructions go thro each function
73   createBBToMImap(M);
74   
75   //map of LLVM Instruction to Machine Instruction 
76   createLLVMToMImap(M);
77   
78   
79   // Write map to the sparc assembly stream
80   // Start by writing out the basic block to first and last
81   // machine instruction map to the .s file
82   Out << "\n\n!BB TO MI MAP\n";
83   Out << "\t.section \".data\"\n\t.align 8\n";
84   Out << "\t.global BBMIMap\n";
85   Out << "BBMIMap:\n";
86   //add stream object here that will contain info about the map
87   //add object to write this out to the .s file
88   for (vector<vector<int> >::iterator BBmapI = 
89          BBmap.begin(), BBmapE = BBmap.end(); BBmapI != BBmapE;
90        ++BBmapI){
91     writeNumber((*BBmapI)[0]);
92     writeNumber((*BBmapI)[1]);
93     writeNumber((*BBmapI)[2]);
94     writeNumber((*BBmapI)[3]);
95   }
96   
97   Out << "\t.type BBMIMap,#object\n";
98   Out << "\t.size BBMIMap,"<<BBmap.size() << "\n";
99   
100   //output length info
101   Out <<"\n\n!LLVM BB MAP Length\n\t.section \".bbdata";
102   Out << "\",#alloc,#write\n\t.global BBMIMap_length\n\t.align 4\n\t.type BBMIMap_length,";
103   Out <<"#object\n\t.size BBMIMap_length,4\nBBMIMap_length:\n\t.word "
104       << ((BBmap.size())*4)<<"\n\n\n\n";
105  
106
107   //Now write out the LLVM instruction to the corresponding
108   //machine instruction map
109   Out << "!LLVM I TO MI MAP\n";
110   Out << "\t.section\".data\"\n\t.align 8\n";
111   Out << "\t.global LMIMap\n";
112   Out << "LMIMap:\n";
113   //add stream object here that will contain info about the map
114   //add object to write this out to the .s file
115   for (vector<vector<int> >::iterator MImapI = 
116          MImap.begin(), MImapE = MImap.end(); MImapI != MImapE;
117        ++MImapI){
118     writeNumber((*MImapI)[0]);
119     writeNumber((*MImapI)[1]);
120     writeNumber((*MImapI)[2]);
121     writeNumber((*MImapI)[3]);
122   }
123   Out << "\t.type LMIMap,#object\n";
124   Out << "\t.size LMIMap,"<<MImap.size() << "\n";
125   //output length info
126   Out <<"\n\n!LLVM MI MAP Length\n\t.section\".llvmdata";
127   Out << "\",#alloc,#write\n\t.global LMIMap_length\n\t.align 4\n\t.type LMIMap_length,";
128   Out <<"#object\n\t.size LMIMap_length,4\nLMIMap_length:\n\t.word "
129       << ((MImap.size())*4)<<"\n\n\n\n";
130
131   return false; 
132 }  
133
134 //write out information as .byte directives
135 void getMappingInfoForFunction::writeNumber(int X) {
136   do {
137     int tmp = X & 127;
138     X >>= 7;
139     if (X) tmp |= 128;
140     Out << "\t.byte " << tmp << "\n";    
141   } while(X);
142 }
143
144 //Assign a number to each Function 
145 void getMappingInfoForFunction::createFunctionKey(Module &M){
146   int i = 0;
147   int j = 0;
148   for (Module::iterator FI = M.begin(), FE = M.end();
149        FI != FE; ++FI){
150     //dont count F with 0 BBs
151     if(FI->isExternal()) 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->isExternal()) 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 //Assign a number to each MI wrt beginning of the BB
174 void getMappingInfoForFunction::createMachineInstructionKey(Module &M){
175   for (Module::iterator FI = M.begin(), FE = M.end(); 
176        FI != FE; ++FI){
177     if(FI->isExternal()) continue;
178     for (Function::iterator BI=FI->begin(), BE=FI->end(); 
179          BI != BE; ++BI){
180       MachineCodeForBasicBlock &miBB = MachineCodeForBasicBlock::get(BI);
181       int j = 0;
182       for (MachineCodeForBasicBlock::iterator miI = miBB.begin(),
183              miE = miBB.end(); miI != miE; ++miI, ++j){
184         MIkey[*miI] = j;
185       }
186     }
187   }
188 }
189
190 //BBtoMImap: contains F#, BB#, 
191 //              MI#[wrt beginning of F], #MI in BB
192 void getMappingInfoForFunction::createBBToMImap(Module &M){
193
194   for (Module::iterator FI = M.begin(), FE = M.end();
195        FI != FE; ++FI){ 
196     if(FI->isExternal())continue;
197     int i = 0;
198     for (Function::iterator BI = FI->begin(), 
199            BE = FI->end(); BI != BE; ++BI){
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 F#
207       oneBB.push_back(Fkey[FI]);
208       //add BB#
209       oneBB.push_back( i );
210       //add the MI#[wrt the beginning of F]
211       oneBB.push_back( BBkey[ miBB[0] ]);
212       //add the # of MI
213       oneBB.push_back(miBB.size());
214       ++i;
215
216     }
217   }
218 }
219
220 //LLVMtoMImap: contains F#, BB#, LLVM#, 
221 //                           MIs[wrt to beginning of BB] 
222 void getMappingInfoForFunction::createLLVMToMImap(Module &M){
223   
224   for (Module::iterator FI = M.begin(), FE = M.end();
225        FI != FE; ++FI){
226     if(FI->isExternal()) continue;
227     int i =0;
228     for (Function::iterator BI = FI->begin(),  BE = FI->end(); 
229          BI != BE; ++BI, ++i){
230       int j = 0;
231       for (BasicBlock::iterator II = BI->begin(), 
232              IE = BI->end(); II != IE; ++II, ++j){
233         MachineCodeForInstruction& miI = 
234           MachineCodeForInstruction::get(II);
235         //do for each corr. MI
236         for (MachineCodeForInstruction::iterator miII = miI.begin(), 
237                miIE = miI.end(); miII != miIE; ++miII){
238
239           MImap.push_back(vector<int>());
240           vector<int> &oneMI = MImap.back();
241           oneMI.reserve(4);
242           
243           //add F#
244           oneMI.push_back(Fkey[FI]);
245           //add BB#
246           oneMI.push_back(i);
247           //add LLVM Instr#
248           oneMI.push_back(j);
249           //add MI#[wrt to beginning of BB]
250           oneMI.push_back(MIkey[*miII]);
251         }
252       }
253     } 
254   }
255 }
256
257