blob: 1dc668b398ec6f083d03007f5b0f4d5c04ef3b86 [file] [log] [blame]
Brian Gaeke3ca4fcc2004-04-25 07:04:49 +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 Gaeke849c7b52004-10-19 05:15:21 +000011// which creates a map between MachineBasicBlocks and
Brian Gaekeaeab1e12003-06-04 22:07:12 +000012// MachineInstrs (the "BB TO MI MAP").
Brian Gaekee14ccaf2003-06-03 07:56:05 +000013//
14// As a side effect, it outputs this information as .byte directives to
15// the assembly file. The output is designed to survive the SPARC assembler,
16// in order that the Reoptimizer may read it in from memory later when the
17// binary is loaded. Therefore, it may contain some hidden SPARC-architecture
18// dependencies. Currently this question is purely theoretical as the
19// Reoptimizer works only on the SPARC.
Anand Shuklab85d2652002-08-27 22:47:33 +000020//
Brian Gaekeaeab1e12003-06-04 22:07:12 +000021// The BB TO MI MAP consists of a three-element tuple for each
22// MachineBasicBlock in a function, ordered from begin() to end() of
23// its MachineFunction: first, the index of the MachineBasicBlock in the
24// function; second, the number of the MachineBasicBlock in the function
25// as computed by create_BB_to_MInumber_Key; and third, the number of
26// MachineInstrs in the MachineBasicBlock.
27//
Anand Shuklab85d2652002-08-27 22:47:33 +000028//===--------------------------------------------------------------------===//
29
Chris Lattner48e60792003-08-13 02:38:16 +000030#include "MappingInfo.h"
Anand Shuklab85d2652002-08-27 22:47:33 +000031#include "llvm/Pass.h"
32#include "llvm/Module.h"
Misha Brukmanb7551ef2002-10-28 20:00:31 +000033#include "llvm/CodeGen/MachineFunction.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000034#include "llvm/ADT/StringExtras.h"
Anand Shuklab85d2652002-08-27 22:47:33 +000035
Brian Gaeked0fde302003-11-11 22:41:34 +000036namespace llvm {
37
Anand Shuklab85d2652002-08-27 22:47:33 +000038namespace {
Brian Gaeke866dc1d2003-09-18 17:37:25 +000039 class MappingInfoAsmPrinter : public FunctionPass {
Anand Shuklab85d2652002-08-27 22:47:33 +000040 std::ostream &Out;
41 public:
Brian Gaeke866dc1d2003-09-18 17:37:25 +000042 MappingInfoAsmPrinter(std::ostream &out) : Out(out){}
Brian Gaekeaeab1e12003-06-04 22:07:12 +000043 const char *getPassName () const { return "Instr. Mapping Info Collector"; }
Anand Shuklab85d2652002-08-27 22:47:33 +000044 bool runOnFunction(Function &FI);
Brian Gaekeaeab1e12003-06-04 22:07:12 +000045 typedef std::map<const MachineInstr*, unsigned> InstructionKey;
Anand Shuklab85d2652002-08-27 22:47:33 +000046 private:
Brian Gaekeaeab1e12003-06-04 22:07:12 +000047 MappingInfo *currentOutputMap;
48 std::map<Function *, unsigned> Fkey; // Function # for all functions.
Anand Shuklab85d2652002-08-27 22:47:33 +000049 bool doInitialization(Module &M);
Brian Gaekeaeab1e12003-06-04 22:07:12 +000050 void create_BB_to_MInumber_Key(Function &FI, InstructionKey &key);
Brian Gaekeaeab1e12003-06-04 22:07:12 +000051 void buildBBMIMap (Function &FI, MappingInfo &Map);
Brian Gaekeaeab1e12003-06-04 22:07:12 +000052 void writeNumber(unsigned X);
53 void selectOutputMap (MappingInfo &m) { currentOutputMap = &m; }
54 void outByte (unsigned char b) { currentOutputMap->outByte (b); }
Brian Gaeke866dc1d2003-09-18 17:37:25 +000055 bool doFinalization (Module &M);
Anand Shuklab85d2652002-08-27 22:47:33 +000056 };
57}
58
Brian Gaeke866dc1d2003-09-18 17:37:25 +000059/// getMappingInfoAsmPrinterPass - Static factory method: returns a new
60/// MappingInfoAsmPrinter Pass object, which uses OUT as its output
61/// stream for assembly output.
62///
Chris Lattnerb12914b2004-09-20 04:48:05 +000063ModulePass *getMappingInfoAsmPrinterPass(std::ostream &out){
64 return new MappingInfoAsmPrinter(out);
Anand Shuklab85d2652002-08-27 22:47:33 +000065}
66
Brian Gaeke866dc1d2003-09-18 17:37:25 +000067/// runOnFunction - Builds up the maps for the given function FI and then
Brian Gaekefc97c8b2003-06-03 19:30:15 +000068/// writes them out as assembly code to the current output stream OUT.
Brian Gaekee14ccaf2003-06-03 07:56:05 +000069/// This is an entry point to the pass, called by the PassManager.
Brian Gaeke866dc1d2003-09-18 17:37:25 +000070///
71bool MappingInfoAsmPrinter::runOnFunction(Function &FI) {
Brian Gaekefc97c8b2003-06-03 19:30:15 +000072 unsigned num = Fkey[&FI]; // Function number for the current function.
Anand Shuklab85d2652002-08-27 22:47:33 +000073
Brian Gaeke849c7b52004-10-19 05:15:21 +000074 // Create an object to hold the map, then build the map.
Brian Gaekeaeab1e12003-06-04 22:07:12 +000075 MappingInfo BBMIMap ("BB TO MI MAP", "BBMIMap", num);
Brian Gaekeaeab1e12003-06-04 22:07:12 +000076 buildBBMIMap (FI, BBMIMap);
77
Brian Gaekefc97c8b2003-06-03 19:30:15 +000078 // Now, write out the maps.
Brian Gaekeaeab1e12003-06-04 22:07:12 +000079 BBMIMap.dumpAssembly (Out);
Brian Gaekefc97c8b2003-06-03 19:30:15 +000080
Anand Shuklab85d2652002-08-27 22:47:33 +000081 return false;
82}
83
Brian Gaeke866dc1d2003-09-18 17:37:25 +000084/// writeNumber - Write out the number X as a sequence of .byte
Brian Gaekefc97c8b2003-06-03 19:30:15 +000085/// directives to the current output stream Out. This method performs a
86/// run-length encoding of the unsigned integers X that are output.
Brian Gaeke866dc1d2003-09-18 17:37:25 +000087///
88void MappingInfoAsmPrinter::writeNumber(unsigned X) {
Anand Shuklab85d2652002-08-27 22:47:33 +000089 unsigned i=0;
90 do {
91 unsigned tmp = X & 127;
92 X >>= 7;
93 if (X) tmp |= 128;
Brian Gaekeaeab1e12003-06-04 22:07:12 +000094 outByte (tmp);
Anand Shuklab85d2652002-08-27 22:47:33 +000095 ++i;
96 } while(X);
Anand Shuklab85d2652002-08-27 22:47:33 +000097}
98
Brian Gaeke866dc1d2003-09-18 17:37:25 +000099/// doInitialization - Assign a number to each Function, as follows:
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000100/// Functions are numbered starting at 0 at the begin() of each Module.
101/// Functions which are External (and thus have 0 basic blocks) are not
102/// inserted into the maps, and are not assigned a number. The side-effect
103/// of this method is to fill in Fkey to contain the mapping from Functions
104/// to numbers. (This method is called automatically by the PassManager.)
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000105///
106bool MappingInfoAsmPrinter::doInitialization(Module &M) {
Anand Shuklab85d2652002-08-27 22:47:33 +0000107 unsigned i = 0;
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000108 for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) {
109 if (FI->isExternal()) continue;
Anand Shuklab85d2652002-08-27 22:47:33 +0000110 Fkey[FI] = i;
111 ++i;
112 }
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000113 return false; // Success.
Anand Shuklab85d2652002-08-27 22:47:33 +0000114}
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000115
116/// create_BB_to_MInumber_Key -- Assign a number to each MachineBasicBlock
117/// in the given Function, as follows: Numbering starts at zero in each
118/// Function. MachineBasicBlocks are numbered from begin() to end()
119/// in the Function's corresponding MachineFunction. Each successive
120/// MachineBasicBlock increments the numbering by the number of instructions
Misha Brukmancf00c4a2003-10-10 17:57:28 +0000121/// it contains. The side-effect of this method is to fill in the parameter
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000122/// KEY with the mapping of MachineBasicBlocks to numbers. KEY
Brian Gaekee14ccaf2003-06-03 07:56:05 +0000123/// is keyed on MachineInstrs, so each MachineBasicBlock is represented
124/// therein by its first MachineInstr.
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000125///
126void MappingInfoAsmPrinter::create_BB_to_MInumber_Key(Function &FI,
Brian Gaeke849c7b52004-10-19 05:15:21 +0000127 InstructionKey &key) {
Anand Shuklab85d2652002-08-27 22:47:33 +0000128 unsigned i = 0;
Misha Brukmanb7551ef2002-10-28 20:00:31 +0000129 MachineFunction &MF = MachineFunction::get(&FI);
130 for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
131 BI != BE; ++BI) {
132 MachineBasicBlock &miBB = *BI;
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000133 key[&miBB.front()] = i;
Anand Shuklab85d2652002-08-27 22:47:33 +0000134 i = i+(miBB.size());
135 }
136}
137
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000138/// buildBBMIMap - Build the BB TO MI MAP for the function FI,
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000139/// and save it into the parameter MAP.
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000140///
141void MappingInfoAsmPrinter::buildBBMIMap(Function &FI, MappingInfo &Map) {
Misha Brukmanb7551ef2002-10-28 20:00:31 +0000142 unsigned bb = 0;
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000143
144 // First build temporary table used to write out the map.
145 InstructionKey BBkey;
146 create_BB_to_MInumber_Key(FI, BBkey);
147
148 selectOutputMap (Map);
Misha Brukmanb7551ef2002-10-28 20:00:31 +0000149 MachineFunction &MF = MachineFunction::get(&FI);
150 for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
151 BI != BE; ++BI, ++bb) {
152 MachineBasicBlock &miBB = *BI;
Anand Shuklab85d2652002-08-27 22:47:33 +0000153 writeNumber(bb);
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000154 writeNumber(BBkey[&miBB.front()]);
Anand Shuklab85d2652002-08-27 22:47:33 +0000155 writeNumber(miBB.size());
156 }
157}
158
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000159void MappingInfo::byteVector::dumpAssembly (std::ostream &Out) {
160 for (iterator i = begin (), e = end (); i != e; ++i)
161 Out << ".byte " << (int)*i << "\n";
162}
163
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000164static void writePrologue (std::ostream &Out, const std::string &comment,
165 const std::string &symName) {
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000166 // Prologue:
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000167 // Output a comment describing the object.
Brian Gaekeaeab1e12003-06-04 22:07:12 +0000168 Out << "!" << comment << "\n";
169 // Switch the current section to .rodata in the assembly output:
170 Out << "\t.section \".rodata\"\n\t.align 8\n";
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000171 // Output a global symbol naming the object:
172 Out << "\t.global " << symName << "\n";
173 Out << "\t.type " << symName << ",#object\n";
174 Out << symName << ":\n";
Anand Shuklab85d2652002-08-27 22:47:33 +0000175}
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000176
177static void writeEpilogue (std::ostream &Out, const std::string &symName) {
178 // Epilogue:
179 // Output a local symbol marking the end of the object:
180 Out << ".end_" << symName << ":\n";
181 // Output size directive giving the size of the object:
182 Out << "\t.size " << symName << ", .end_" << symName << "-" << symName
183 << "\n";
184}
185
186void MappingInfo::dumpAssembly (std::ostream &Out) {
187 const std::string &name (symbolPrefix + utostr (functionNumber));
188 writePrologue (Out, comment, name);
189 // The LMIMap and BBMIMap are supposed to start with a length word:
190 Out << "\t.word .end_" << name << "-" << name << "\n";
191 bytes.dumpAssembly (Out);
192 writeEpilogue (Out, name);
193}
194
195/// doFinalization - This method writes out two tables, named
196/// FunctionBB and FunctionLI, which map Function numbers (as in
197/// doInitialization) to the BBMIMap and LMIMap tables. (This used to
198/// be the "FunctionInfo" pass.)
199///
200bool MappingInfoAsmPrinter::doFinalization (Module &M) {
201 unsigned f;
202
203 writePrologue(Out, "FUNCTION TO BB MAP", "FunctionBB");
204 f=0;
205 for(Module::iterator FI = M.begin (), FE = M.end (); FE != FI; ++FI) {
206 if (FI->isExternal ())
207 continue;
208 Out << "\t.xword BBMIMap" << f << "\n";
209 ++f;
210 }
211 writeEpilogue(Out, "FunctionBB");
212
Brian Gaeke866dc1d2003-09-18 17:37:25 +0000213 return false;
214}
215
Brian Gaeked0fde302003-11-11 22:41:34 +0000216} // End llvm namespace