blob: 999b6030fbead8b3837445f3e05949a19dc1b6d2 [file] [log] [blame]
Anand Shuklab85d2652002-08-27 22:47:33 +00001//===- MappingInfo.cpp - create LLVM info and output to .s file ---------===//
2//
Brian Gaeke866dc1d2003-09-18 17:37:25 +00003// This file contains a FunctionPass called MappingInfoAsmPrinter,
Brian Gaekeaeab1e12003-06-04 22:07:12 +00004// which creates two maps: one between LLVM Instructions and MachineInstrs
5// (the "LLVM I TO MI MAP"), and another between MachineBasicBlocks and
6// MachineInstrs (the "BB TO MI MAP").
Brian Gaekee14ccaf2003-06-03 07:56:05 +00007//
8// As a side effect, it outputs this information as .byte directives to
9// the assembly file. The output is designed to survive the SPARC assembler,
10// in order that the Reoptimizer may read it in from memory later when the
11// binary is loaded. Therefore, it may contain some hidden SPARC-architecture
12// dependencies. Currently this question is purely theoretical as the
13// Reoptimizer works only on the SPARC.
Anand Shuklab85d2652002-08-27 22:47:33 +000014//
Brian Gaekeaeab1e12003-06-04 22:07:12 +000015// The LLVM I TO MI MAP consists of a set of information for each
16// BasicBlock in a Function, ordered from begin() to end(). The information
17// for a BasicBlock consists of
18// 1) its (0-based) index in the Function,
19// 2) the number of LLVM Instructions it contains, and
20// 3) information for each Instruction, in sequence from the begin()
21// to the end() of the BasicBlock. The information for an Instruction
22// consists of
23// 1) its (0-based) index in the BasicBlock,
24// 2) the number of MachineInstrs that correspond to that Instruction
25// (as reported by MachineCodeForInstruction), and
26// 3) the MachineInstr number calculated by create_MI_to_number_Key,
27// for each of the MachineInstrs that correspond to that Instruction.
28//
29// The BB TO MI MAP consists of a three-element tuple for each
30// MachineBasicBlock in a function, ordered from begin() to end() of
31// its MachineFunction: first, the index of the MachineBasicBlock in the
32// function; second, the number of the MachineBasicBlock in the function
33// as computed by create_BB_to_MInumber_Key; and third, the number of
34// MachineInstrs in the MachineBasicBlock.
35//
Anand Shuklab85d2652002-08-27 22:47:33 +000036//===--------------------------------------------------------------------===//
37
Chris Lattner48e60792003-08-13 02:38:16 +000038#include "MappingInfo.h"
Anand Shuklab85d2652002-08-27 22:47:33 +000039#include "llvm/Pass.h"
40#include "llvm/Module.h"
Misha Brukmanb7551ef2002-10-28 20:00:31 +000041#include "llvm/CodeGen/MachineFunction.h"
Anand Shuklab85d2652002-08-27 22:47:33 +000042#include "llvm/CodeGen/MachineCodeForInstruction.h"
Brian Gaeke866dc1d2003-09-18 17:37:25 +000043#include "Support/StringExtras.h"
Anand Shuklab85d2652002-08-27 22:47:33 +000044
Anand Shuklab85d2652002-08-27 22:47:33 +000045namespace {
Brian Gaeke866dc1d2003-09-18 17:37:25 +000046 class MappingInfoAsmPrinter : public FunctionPass {
Anand Shuklab85d2652002-08-27 22:47:33 +000047 std::ostream &Out;
48 public:
Brian Gaeke866dc1d2003-09-18 17:37:25 +000049 MappingInfoAsmPrinter(std::ostream &out) : Out(out){}
Brian Gaekeaeab1e12003-06-04 22:07:12 +000050 const char *getPassName () const { return "Instr. Mapping Info Collector"; }
Anand Shuklab85d2652002-08-27 22:47:33 +000051 bool runOnFunction(Function &FI);
Brian Gaekeaeab1e12003-06-04 22:07:12 +000052 typedef std::map<const MachineInstr*, unsigned> InstructionKey;
Anand Shuklab85d2652002-08-27 22:47:33 +000053 private:
Brian Gaekeaeab1e12003-06-04 22:07:12 +000054 MappingInfo *currentOutputMap;
55 std::map<Function *, unsigned> Fkey; // Function # for all functions.
Anand Shuklab85d2652002-08-27 22:47:33 +000056 bool doInitialization(Module &M);
Brian Gaekeaeab1e12003-06-04 22:07:12 +000057 void create_BB_to_MInumber_Key(Function &FI, InstructionKey &key);
58 void create_MI_to_number_Key(Function &FI, InstructionKey &key);
59 void buildBBMIMap (Function &FI, MappingInfo &Map);
60 void buildLMIMap (Function &FI, MappingInfo &Map);
61 void writeNumber(unsigned X);
62 void selectOutputMap (MappingInfo &m) { currentOutputMap = &m; }
63 void outByte (unsigned char b) { currentOutputMap->outByte (b); }
Brian Gaeke866dc1d2003-09-18 17:37:25 +000064 bool doFinalization (Module &M);
Anand Shuklab85d2652002-08-27 22:47:33 +000065 };
66}
67
Brian Gaeke866dc1d2003-09-18 17:37:25 +000068/// getMappingInfoAsmPrinterPass - Static factory method: returns a new
69/// MappingInfoAsmPrinter Pass object, which uses OUT as its output
70/// stream for assembly output.
71///
72Pass *getMappingInfoAsmPrinterPass(std::ostream &out){
73 return (new MappingInfoAsmPrinter(out));
Anand Shuklab85d2652002-08-27 22:47:33 +000074}
75
Brian Gaeke866dc1d2003-09-18 17:37:25 +000076/// runOnFunction - Builds up the maps for the given function FI and then
Brian Gaekefc97c8b2003-06-03 19:30:15 +000077/// writes them out as assembly code to the current output stream OUT.
Brian Gaekee14ccaf2003-06-03 07:56:05 +000078/// This is an entry point to the pass, called by the PassManager.
Brian Gaeke866dc1d2003-09-18 17:37:25 +000079///
80bool MappingInfoAsmPrinter::runOnFunction(Function &FI) {
Brian Gaekefc97c8b2003-06-03 19:30:15 +000081 unsigned num = Fkey[&FI]; // Function number for the current function.
Anand Shuklab85d2652002-08-27 22:47:33 +000082
Brian Gaekeaeab1e12003-06-04 22:07:12 +000083 // Create objects to hold the maps.
84 MappingInfo LMIMap ("LLVM I TO MI MAP", "LMIMap", num);
85 MappingInfo BBMIMap ("BB TO MI MAP", "BBMIMap", num);
86
87 // Now, build the maps.
88 buildLMIMap (FI, LMIMap);
89 buildBBMIMap (FI, BBMIMap);
90
Brian Gaekefc97c8b2003-06-03 19:30:15 +000091 // Now, write out the maps.
Brian Gaekeaeab1e12003-06-04 22:07:12 +000092 LMIMap.dumpAssembly (Out);
93 BBMIMap.dumpAssembly (Out);
Brian Gaekefc97c8b2003-06-03 19:30:15 +000094
Anand Shuklab85d2652002-08-27 22:47:33 +000095 return false;
96}
97
Brian Gaeke866dc1d2003-09-18 17:37:25 +000098/// writeNumber - Write out the number X as a sequence of .byte
Brian Gaekefc97c8b2003-06-03 19:30:15 +000099/// directives to the current output stream Out. This method performs a
100/// run-length encoding of the unsigned integers X that are output.
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000101///
102void MappingInfoAsmPrinter::writeNumber(unsigned X) {
Anand Shuklab85d2652002-08-27 22:47:33 +0000103 unsigned i=0;
104 do {
105 unsigned tmp = X & 127;
106 X >>= 7;
107 if (X) tmp |= 128;
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000108 outByte (tmp);
Anand Shuklab85d2652002-08-27 22:47:33 +0000109 ++i;
110 } while(X);
Anand Shuklab85d2652002-08-27 22:47:33 +0000111}
112
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000113/// doInitialization - Assign a number to each Function, as follows:
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000114/// Functions are numbered starting at 0 at the begin() of each Module.
115/// Functions which are External (and thus have 0 basic blocks) are not
116/// inserted into the maps, and are not assigned a number. The side-effect
117/// of this method is to fill in Fkey to contain the mapping from Functions
118/// to numbers. (This method is called automatically by the PassManager.)
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000119///
120bool MappingInfoAsmPrinter::doInitialization(Module &M) {
Anand Shuklab85d2652002-08-27 22:47:33 +0000121 unsigned i = 0;
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000122 for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) {
123 if (FI->isExternal()) continue;
Anand Shuklab85d2652002-08-27 22:47:33 +0000124 Fkey[FI] = i;
125 ++i;
126 }
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000127 return false; // Success.
Anand Shuklab85d2652002-08-27 22:47:33 +0000128}
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000129
130/// create_BB_to_MInumber_Key -- Assign a number to each MachineBasicBlock
131/// in the given Function, as follows: Numbering starts at zero in each
132/// Function. MachineBasicBlocks are numbered from begin() to end()
133/// in the Function's corresponding MachineFunction. Each successive
134/// MachineBasicBlock increments the numbering by the number of instructions
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000135/// it contains. The side-effect of this method is to fill in the paramete
136/// KEY with the mapping of MachineBasicBlocks to numbers. KEY
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000137/// is keyed on MachineInstrs, so each MachineBasicBlock is represented
138/// therein by its first MachineInstr.
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000139///
140void MappingInfoAsmPrinter::create_BB_to_MInumber_Key(Function &FI,
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000141 InstructionKey &key) {
Anand Shuklab85d2652002-08-27 22:47:33 +0000142 unsigned i = 0;
Misha Brukmanb7551ef2002-10-28 20:00:31 +0000143 MachineFunction &MF = MachineFunction::get(&FI);
144 for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
145 BI != BE; ++BI) {
146 MachineBasicBlock &miBB = *BI;
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000147 key[miBB[0]] = i;
Anand Shuklab85d2652002-08-27 22:47:33 +0000148 i = i+(miBB.size());
149 }
150}
151
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000152/// create_MI_to_number_Key - Assign a number to each MachineInstr
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000153/// in the given Function with respect to its enclosing MachineBasicBlock, as
154/// follows: Numberings start at 0 in each MachineBasicBlock. MachineInstrs
155/// are numbered from begin() to end() in their MachineBasicBlock. Each
156/// MachineInstr is numbered, then the numbering is incremented by 1. The
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000157/// side-effect of this method is to fill in the parameter KEY
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000158/// with the mapping from MachineInstrs to numbers.
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000159///
160void MappingInfoAsmPrinter::create_MI_to_number_Key(Function &FI,
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000161 InstructionKey &key) {
Misha Brukmanb7551ef2002-10-28 20:00:31 +0000162 MachineFunction &MF = MachineFunction::get(&FI);
163 for (MachineFunction::iterator BI=MF.begin(), BE=MF.end(); BI != BE; ++BI) {
164 MachineBasicBlock &miBB = *BI;
Anand Shuklab85d2652002-08-27 22:47:33 +0000165 unsigned j = 0;
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000166 for(MachineBasicBlock::iterator miI = miBB.begin(), miE = miBB.end();
167 miI != miE; ++miI, ++j) {
168 key[*miI] = j;
Anand Shuklab85d2652002-08-27 22:47:33 +0000169 }
170 }
171}
172
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000173/// buildBBMIMap - Build the BB TO MI MAP for the function FI,
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000174/// and save it into the parameter MAP.
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000175///
176void MappingInfoAsmPrinter::buildBBMIMap(Function &FI, MappingInfo &Map) {
Misha Brukmanb7551ef2002-10-28 20:00:31 +0000177 unsigned bb = 0;
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000178
179 // First build temporary table used to write out the map.
180 InstructionKey BBkey;
181 create_BB_to_MInumber_Key(FI, BBkey);
182
183 selectOutputMap (Map);
Misha Brukmanb7551ef2002-10-28 20:00:31 +0000184 MachineFunction &MF = MachineFunction::get(&FI);
185 for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
186 BI != BE; ++BI, ++bb) {
187 MachineBasicBlock &miBB = *BI;
Anand Shuklab85d2652002-08-27 22:47:33 +0000188 writeNumber(bb);
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000189 writeNumber(BBkey[miBB[0]]);
Anand Shuklab85d2652002-08-27 22:47:33 +0000190 writeNumber(miBB.size());
191 }
192}
193
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000194/// buildLMIMap - Build the LLVM I TO MI MAP for the function FI,
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000195/// and save it into the parameter MAP.
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000196///
197void MappingInfoAsmPrinter::buildLMIMap(Function &FI, MappingInfo &Map) {
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000198 unsigned bb = 0;
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000199 // First build temporary table used to write out the map.
200 InstructionKey MIkey;
201 create_MI_to_number_Key(FI, MIkey);
202
203 selectOutputMap (Map);
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000204 for (Function::iterator BI = FI.begin(), BE = FI.end();
Misha Brukmanb7551ef2002-10-28 20:00:31 +0000205 BI != BE; ++BI, ++bb) {
Anand Shuklab85d2652002-08-27 22:47:33 +0000206 unsigned li = 0;
207 writeNumber(bb);
Anand Shuklab85d2652002-08-27 22:47:33 +0000208 writeNumber(BI->size());
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000209 for (BasicBlock::iterator II = BI->begin(), IE = BI->end(); II != IE;
210 ++II, ++li) {
211 MachineCodeForInstruction& miI = MachineCodeForInstruction::get(II);
Anand Shuklab85d2652002-08-27 22:47:33 +0000212 writeNumber(li);
Anand Shuklab3794702002-09-17 20:24:46 +0000213 writeNumber(miI.size());
Anand Shuklab85d2652002-08-27 22:47:33 +0000214 for (MachineCodeForInstruction::iterator miII = miI.begin(),
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000215 miIE = miI.end(); miII != miIE; ++miII) {
216 writeNumber(MIkey[*miII]);
Anand Shuklab85d2652002-08-27 22:47:33 +0000217 }
218 }
219 }
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000220}
221
222void MappingInfo::byteVector::dumpAssembly (std::ostream &Out) {
223 for (iterator i = begin (), e = end (); i != e; ++i)
224 Out << ".byte " << (int)*i << "\n";
225}
226
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000227static void writePrologue (std::ostream &Out, const std::string &comment,
228 const std::string &symName) {
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000229 // Prologue:
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000230 // Output a comment describing the object.
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000231 Out << "!" << comment << "\n";
232 // Switch the current section to .rodata in the assembly output:
233 Out << "\t.section \".rodata\"\n\t.align 8\n";
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000234 // Output a global symbol naming the object:
235 Out << "\t.global " << symName << "\n";
236 Out << "\t.type " << symName << ",#object\n";
237 Out << symName << ":\n";
Anand Shuklab85d2652002-08-27 22:47:33 +0000238}
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000239
240static void writeEpilogue (std::ostream &Out, const std::string &symName) {
241 // Epilogue:
242 // Output a local symbol marking the end of the object:
243 Out << ".end_" << symName << ":\n";
244 // Output size directive giving the size of the object:
245 Out << "\t.size " << symName << ", .end_" << symName << "-" << symName
246 << "\n";
247}
248
249void MappingInfo::dumpAssembly (std::ostream &Out) {
250 const std::string &name (symbolPrefix + utostr (functionNumber));
251 writePrologue (Out, comment, name);
252 // The LMIMap and BBMIMap are supposed to start with a length word:
253 Out << "\t.word .end_" << name << "-" << name << "\n";
254 bytes.dumpAssembly (Out);
255 writeEpilogue (Out, name);
256}
257
258/// doFinalization - This method writes out two tables, named
259/// FunctionBB and FunctionLI, which map Function numbers (as in
260/// doInitialization) to the BBMIMap and LMIMap tables. (This used to
261/// be the "FunctionInfo" pass.)
262///
263bool MappingInfoAsmPrinter::doFinalization (Module &M) {
264 unsigned f;
265
266 writePrologue(Out, "FUNCTION TO BB MAP", "FunctionBB");
267 f=0;
268 for(Module::iterator FI = M.begin (), FE = M.end (); FE != FI; ++FI) {
269 if (FI->isExternal ())
270 continue;
271 Out << "\t.xword BBMIMap" << f << "\n";
272 ++f;
273 }
274 writeEpilogue(Out, "FunctionBB");
275
276 writePrologue(Out, "FUNCTION TO LI MAP", "FunctionLI");
277 f=0;
278 for(Module::iterator FI = M.begin (), FE = M.end (); FE != FI; ++FI) {
279 if (FI->isExternal ())
280 continue;
281 Out << "\t.xword LMIMap" << f << "\n";
282 ++f;
283 }
284 writeEpilogue(Out, "FunctionLI");
285
286 return false;
287}
288