blob: db03f13b976086b186ba13dcba4a535e88a9e741 [file] [log] [blame]
Anand Shuklab85d2652002-08-27 22:47:33 +00001//===- MappingInfo.cpp - create LLVM info and output to .s file ---------===//
John Criswellb576c942003-10-20 19:43:21 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Anand Shuklab85d2652002-08-27 22:47:33 +00009//
Brian Gaeke866dc1d2003-09-18 17:37:25 +000010// This file contains a FunctionPass called MappingInfoAsmPrinter,
Brian Gaekeaeab1e12003-06-04 22:07:12 +000011// which creates two maps: one between LLVM Instructions and MachineInstrs
12// (the "LLVM I TO MI MAP"), and another between MachineBasicBlocks and
13// MachineInstrs (the "BB TO MI MAP").
Brian Gaekee14ccaf2003-06-03 07:56:05 +000014//
15// As a side effect, it outputs this information as .byte directives to
16// the assembly file. The output is designed to survive the SPARC assembler,
17// in order that the Reoptimizer may read it in from memory later when the
18// binary is loaded. Therefore, it may contain some hidden SPARC-architecture
19// dependencies. Currently this question is purely theoretical as the
20// Reoptimizer works only on the SPARC.
Anand Shuklab85d2652002-08-27 22:47:33 +000021//
Brian Gaekeaeab1e12003-06-04 22:07:12 +000022// The LLVM I TO MI MAP consists of a set of information for each
23// BasicBlock in a Function, ordered from begin() to end(). The information
24// for a BasicBlock consists of
25// 1) its (0-based) index in the Function,
26// 2) the number of LLVM Instructions it contains, and
27// 3) information for each Instruction, in sequence from the begin()
28// to the end() of the BasicBlock. The information for an Instruction
29// consists of
30// 1) its (0-based) index in the BasicBlock,
31// 2) the number of MachineInstrs that correspond to that Instruction
32// (as reported by MachineCodeForInstruction), and
33// 3) the MachineInstr number calculated by create_MI_to_number_Key,
34// for each of the MachineInstrs that correspond to that Instruction.
35//
36// The BB TO MI MAP consists of a three-element tuple for each
37// MachineBasicBlock in a function, ordered from begin() to end() of
38// its MachineFunction: first, the index of the MachineBasicBlock in the
39// function; second, the number of the MachineBasicBlock in the function
40// as computed by create_BB_to_MInumber_Key; and third, the number of
41// MachineInstrs in the MachineBasicBlock.
42//
Anand Shuklab85d2652002-08-27 22:47:33 +000043//===--------------------------------------------------------------------===//
44
Chris Lattner48e60792003-08-13 02:38:16 +000045#include "MappingInfo.h"
Anand Shuklab85d2652002-08-27 22:47:33 +000046#include "llvm/Pass.h"
47#include "llvm/Module.h"
Misha Brukmanb7551ef2002-10-28 20:00:31 +000048#include "llvm/CodeGen/MachineFunction.h"
Anand Shuklab85d2652002-08-27 22:47:33 +000049#include "llvm/CodeGen/MachineCodeForInstruction.h"
Brian Gaeke866dc1d2003-09-18 17:37:25 +000050#include "Support/StringExtras.h"
Anand Shuklab85d2652002-08-27 22:47:33 +000051
Anand Shuklab85d2652002-08-27 22:47:33 +000052namespace {
Brian Gaeke866dc1d2003-09-18 17:37:25 +000053 class MappingInfoAsmPrinter : public FunctionPass {
Anand Shuklab85d2652002-08-27 22:47:33 +000054 std::ostream &Out;
55 public:
Brian Gaeke866dc1d2003-09-18 17:37:25 +000056 MappingInfoAsmPrinter(std::ostream &out) : Out(out){}
Brian Gaekeaeab1e12003-06-04 22:07:12 +000057 const char *getPassName () const { return "Instr. Mapping Info Collector"; }
Anand Shuklab85d2652002-08-27 22:47:33 +000058 bool runOnFunction(Function &FI);
Brian Gaekeaeab1e12003-06-04 22:07:12 +000059 typedef std::map<const MachineInstr*, unsigned> InstructionKey;
Anand Shuklab85d2652002-08-27 22:47:33 +000060 private:
Brian Gaekeaeab1e12003-06-04 22:07:12 +000061 MappingInfo *currentOutputMap;
62 std::map<Function *, unsigned> Fkey; // Function # for all functions.
Anand Shuklab85d2652002-08-27 22:47:33 +000063 bool doInitialization(Module &M);
Brian Gaekeaeab1e12003-06-04 22:07:12 +000064 void create_BB_to_MInumber_Key(Function &FI, InstructionKey &key);
65 void create_MI_to_number_Key(Function &FI, InstructionKey &key);
66 void buildBBMIMap (Function &FI, MappingInfo &Map);
67 void buildLMIMap (Function &FI, MappingInfo &Map);
68 void writeNumber(unsigned X);
69 void selectOutputMap (MappingInfo &m) { currentOutputMap = &m; }
70 void outByte (unsigned char b) { currentOutputMap->outByte (b); }
Brian Gaeke866dc1d2003-09-18 17:37:25 +000071 bool doFinalization (Module &M);
Anand Shuklab85d2652002-08-27 22:47:33 +000072 };
73}
74
Brian Gaeke866dc1d2003-09-18 17:37:25 +000075/// getMappingInfoAsmPrinterPass - Static factory method: returns a new
76/// MappingInfoAsmPrinter Pass object, which uses OUT as its output
77/// stream for assembly output.
78///
79Pass *getMappingInfoAsmPrinterPass(std::ostream &out){
80 return (new MappingInfoAsmPrinter(out));
Anand Shuklab85d2652002-08-27 22:47:33 +000081}
82
Brian Gaeke866dc1d2003-09-18 17:37:25 +000083/// runOnFunction - Builds up the maps for the given function FI and then
Brian Gaekefc97c8b2003-06-03 19:30:15 +000084/// writes them out as assembly code to the current output stream OUT.
Brian Gaekee14ccaf2003-06-03 07:56:05 +000085/// This is an entry point to the pass, called by the PassManager.
Brian Gaeke866dc1d2003-09-18 17:37:25 +000086///
87bool MappingInfoAsmPrinter::runOnFunction(Function &FI) {
Brian Gaekefc97c8b2003-06-03 19:30:15 +000088 unsigned num = Fkey[&FI]; // Function number for the current function.
Anand Shuklab85d2652002-08-27 22:47:33 +000089
Brian Gaekeaeab1e12003-06-04 22:07:12 +000090 // Create objects to hold the maps.
91 MappingInfo LMIMap ("LLVM I TO MI MAP", "LMIMap", num);
92 MappingInfo BBMIMap ("BB TO MI MAP", "BBMIMap", num);
93
94 // Now, build the maps.
95 buildLMIMap (FI, LMIMap);
96 buildBBMIMap (FI, BBMIMap);
97
Brian Gaekefc97c8b2003-06-03 19:30:15 +000098 // Now, write out the maps.
Brian Gaekeaeab1e12003-06-04 22:07:12 +000099 LMIMap.dumpAssembly (Out);
100 BBMIMap.dumpAssembly (Out);
Brian Gaekefc97c8b2003-06-03 19:30:15 +0000101
Anand Shuklab85d2652002-08-27 22:47:33 +0000102 return false;
103}
104
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000105/// writeNumber - Write out the number X as a sequence of .byte
Brian Gaekefc97c8b2003-06-03 19:30:15 +0000106/// directives to the current output stream Out. This method performs a
107/// run-length encoding of the unsigned integers X that are output.
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000108///
109void MappingInfoAsmPrinter::writeNumber(unsigned X) {
Anand Shuklab85d2652002-08-27 22:47:33 +0000110 unsigned i=0;
111 do {
112 unsigned tmp = X & 127;
113 X >>= 7;
114 if (X) tmp |= 128;
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000115 outByte (tmp);
Anand Shuklab85d2652002-08-27 22:47:33 +0000116 ++i;
117 } while(X);
Anand Shuklab85d2652002-08-27 22:47:33 +0000118}
119
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000120/// doInitialization - Assign a number to each Function, as follows:
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000121/// Functions are numbered starting at 0 at the begin() of each Module.
122/// Functions which are External (and thus have 0 basic blocks) are not
123/// inserted into the maps, and are not assigned a number. The side-effect
124/// of this method is to fill in Fkey to contain the mapping from Functions
125/// to numbers. (This method is called automatically by the PassManager.)
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000126///
127bool MappingInfoAsmPrinter::doInitialization(Module &M) {
Anand Shuklab85d2652002-08-27 22:47:33 +0000128 unsigned i = 0;
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000129 for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) {
130 if (FI->isExternal()) continue;
Anand Shuklab85d2652002-08-27 22:47:33 +0000131 Fkey[FI] = i;
132 ++i;
133 }
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000134 return false; // Success.
Anand Shuklab85d2652002-08-27 22:47:33 +0000135}
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000136
137/// create_BB_to_MInumber_Key -- Assign a number to each MachineBasicBlock
138/// in the given Function, as follows: Numbering starts at zero in each
139/// Function. MachineBasicBlocks are numbered from begin() to end()
140/// in the Function's corresponding MachineFunction. Each successive
141/// MachineBasicBlock increments the numbering by the number of instructions
Misha Brukmancf00c4a2003-10-10 17:57:28 +0000142/// it contains. The side-effect of this method is to fill in the parameter
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000143/// KEY with the mapping of MachineBasicBlocks to numbers. KEY
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000144/// is keyed on MachineInstrs, so each MachineBasicBlock is represented
145/// therein by its first MachineInstr.
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000146///
147void MappingInfoAsmPrinter::create_BB_to_MInumber_Key(Function &FI,
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000148 InstructionKey &key) {
Anand Shuklab85d2652002-08-27 22:47:33 +0000149 unsigned i = 0;
Misha Brukmanb7551ef2002-10-28 20:00:31 +0000150 MachineFunction &MF = MachineFunction::get(&FI);
151 for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
152 BI != BE; ++BI) {
153 MachineBasicBlock &miBB = *BI;
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000154 key[miBB[0]] = i;
Anand Shuklab85d2652002-08-27 22:47:33 +0000155 i = i+(miBB.size());
156 }
157}
158
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000159/// create_MI_to_number_Key - Assign a number to each MachineInstr
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000160/// in the given Function with respect to its enclosing MachineBasicBlock, as
161/// follows: Numberings start at 0 in each MachineBasicBlock. MachineInstrs
162/// are numbered from begin() to end() in their MachineBasicBlock. Each
163/// MachineInstr is numbered, then the numbering is incremented by 1. The
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000164/// side-effect of this method is to fill in the parameter KEY
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000165/// with the mapping from MachineInstrs to numbers.
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000166///
167void MappingInfoAsmPrinter::create_MI_to_number_Key(Function &FI,
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000168 InstructionKey &key) {
Misha Brukmanb7551ef2002-10-28 20:00:31 +0000169 MachineFunction &MF = MachineFunction::get(&FI);
170 for (MachineFunction::iterator BI=MF.begin(), BE=MF.end(); BI != BE; ++BI) {
171 MachineBasicBlock &miBB = *BI;
Anand Shuklab85d2652002-08-27 22:47:33 +0000172 unsigned j = 0;
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000173 for(MachineBasicBlock::iterator miI = miBB.begin(), miE = miBB.end();
174 miI != miE; ++miI, ++j) {
175 key[*miI] = j;
Anand Shuklab85d2652002-08-27 22:47:33 +0000176 }
177 }
178}
179
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000180/// buildBBMIMap - Build the BB TO MI MAP for the function FI,
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000181/// and save it into the parameter MAP.
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000182///
183void MappingInfoAsmPrinter::buildBBMIMap(Function &FI, MappingInfo &Map) {
Misha Brukmanb7551ef2002-10-28 20:00:31 +0000184 unsigned bb = 0;
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000185
186 // First build temporary table used to write out the map.
187 InstructionKey BBkey;
188 create_BB_to_MInumber_Key(FI, BBkey);
189
190 selectOutputMap (Map);
Misha Brukmanb7551ef2002-10-28 20:00:31 +0000191 MachineFunction &MF = MachineFunction::get(&FI);
192 for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
193 BI != BE; ++BI, ++bb) {
194 MachineBasicBlock &miBB = *BI;
Anand Shuklab85d2652002-08-27 22:47:33 +0000195 writeNumber(bb);
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000196 writeNumber(BBkey[miBB[0]]);
Anand Shuklab85d2652002-08-27 22:47:33 +0000197 writeNumber(miBB.size());
198 }
199}
200
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000201/// buildLMIMap - Build the LLVM I TO MI MAP for the function FI,
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000202/// and save it into the parameter MAP.
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000203///
204void MappingInfoAsmPrinter::buildLMIMap(Function &FI, MappingInfo &Map) {
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000205 unsigned bb = 0;
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000206 // First build temporary table used to write out the map.
207 InstructionKey MIkey;
208 create_MI_to_number_Key(FI, MIkey);
209
210 selectOutputMap (Map);
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000211 for (Function::iterator BI = FI.begin(), BE = FI.end();
Misha Brukmanb7551ef2002-10-28 20:00:31 +0000212 BI != BE; ++BI, ++bb) {
Anand Shuklab85d2652002-08-27 22:47:33 +0000213 unsigned li = 0;
214 writeNumber(bb);
Anand Shuklab85d2652002-08-27 22:47:33 +0000215 writeNumber(BI->size());
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000216 for (BasicBlock::iterator II = BI->begin(), IE = BI->end(); II != IE;
217 ++II, ++li) {
218 MachineCodeForInstruction& miI = MachineCodeForInstruction::get(II);
Anand Shuklab85d2652002-08-27 22:47:33 +0000219 writeNumber(li);
Anand Shuklab3794702002-09-17 20:24:46 +0000220 writeNumber(miI.size());
Anand Shuklab85d2652002-08-27 22:47:33 +0000221 for (MachineCodeForInstruction::iterator miII = miI.begin(),
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000222 miIE = miI.end(); miII != miIE; ++miII) {
223 writeNumber(MIkey[*miII]);
Anand Shuklab85d2652002-08-27 22:47:33 +0000224 }
225 }
226 }
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000227}
228
229void MappingInfo::byteVector::dumpAssembly (std::ostream &Out) {
230 for (iterator i = begin (), e = end (); i != e; ++i)
231 Out << ".byte " << (int)*i << "\n";
232}
233
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000234static void writePrologue (std::ostream &Out, const std::string &comment,
235 const std::string &symName) {
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000236 // Prologue:
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000237 // Output a comment describing the object.
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000238 Out << "!" << comment << "\n";
239 // Switch the current section to .rodata in the assembly output:
240 Out << "\t.section \".rodata\"\n\t.align 8\n";
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000241 // Output a global symbol naming the object:
242 Out << "\t.global " << symName << "\n";
243 Out << "\t.type " << symName << ",#object\n";
244 Out << symName << ":\n";
Anand Shuklab85d2652002-08-27 22:47:33 +0000245}
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000246
247static void writeEpilogue (std::ostream &Out, const std::string &symName) {
248 // Epilogue:
249 // Output a local symbol marking the end of the object:
250 Out << ".end_" << symName << ":\n";
251 // Output size directive giving the size of the object:
252 Out << "\t.size " << symName << ", .end_" << symName << "-" << symName
253 << "\n";
254}
255
256void MappingInfo::dumpAssembly (std::ostream &Out) {
257 const std::string &name (symbolPrefix + utostr (functionNumber));
258 writePrologue (Out, comment, name);
259 // The LMIMap and BBMIMap are supposed to start with a length word:
260 Out << "\t.word .end_" << name << "-" << name << "\n";
261 bytes.dumpAssembly (Out);
262 writeEpilogue (Out, name);
263}
264
265/// doFinalization - This method writes out two tables, named
266/// FunctionBB and FunctionLI, which map Function numbers (as in
267/// doInitialization) to the BBMIMap and LMIMap tables. (This used to
268/// be the "FunctionInfo" pass.)
269///
270bool MappingInfoAsmPrinter::doFinalization (Module &M) {
271 unsigned f;
272
273 writePrologue(Out, "FUNCTION TO BB MAP", "FunctionBB");
274 f=0;
275 for(Module::iterator FI = M.begin (), FE = M.end (); FE != FI; ++FI) {
276 if (FI->isExternal ())
277 continue;
278 Out << "\t.xword BBMIMap" << f << "\n";
279 ++f;
280 }
281 writeEpilogue(Out, "FunctionBB");
282
283 writePrologue(Out, "FUNCTION TO LI MAP", "FunctionLI");
284 f=0;
285 for(Module::iterator FI = M.begin (), FE = M.end (); FE != FI; ++FI) {
286 if (FI->isExternal ())
287 continue;
288 Out << "\t.xword LMIMap" << f << "\n";
289 ++f;
290 }
291 writeEpilogue(Out, "FunctionLI");
292
293 return false;
294}
295