Brian Gaeke | 3ca4fcc | 2004-04-25 07:04:49 +0000 | [diff] [blame] | 1 | //===- MappingInfo.cpp - create LLVM info and output to .s file -----------===// |
John Criswell | b576c94 | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 2 | // |
| 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 Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 9 | // |
Brian Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 10 | // This file contains a FunctionPass called MappingInfoAsmPrinter, |
Brian Gaeke | 849c7b5 | 2004-10-19 05:15:21 +0000 | [diff] [blame] | 11 | // which creates a map between MachineBasicBlocks and |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 12 | // MachineInstrs (the "BB TO MI MAP"). |
Brian Gaeke | e14ccaf | 2003-06-03 07:56:05 +0000 | [diff] [blame] | 13 | // |
| 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 Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 20 | // |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 21 | // 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 Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 28 | //===--------------------------------------------------------------------===// |
| 29 | |
Chris Lattner | 48e6079 | 2003-08-13 02:38:16 +0000 | [diff] [blame] | 30 | #include "MappingInfo.h" |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 31 | #include "llvm/Pass.h" |
| 32 | #include "llvm/Module.h" |
Misha Brukman | b7551ef | 2002-10-28 20:00:31 +0000 | [diff] [blame] | 33 | #include "llvm/CodeGen/MachineFunction.h" |
Reid Spencer | 551ccae | 2004-09-01 22:55:40 +0000 | [diff] [blame] | 34 | #include "llvm/ADT/StringExtras.h" |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 35 | |
Brian Gaeke | d0fde30 | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 36 | namespace llvm { |
| 37 | |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 38 | namespace { |
Brian Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 39 | class MappingInfoAsmPrinter : public FunctionPass { |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 40 | std::ostream &Out; |
| 41 | public: |
Brian Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 42 | MappingInfoAsmPrinter(std::ostream &out) : Out(out){} |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 43 | const char *getPassName () const { return "Instr. Mapping Info Collector"; } |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 44 | bool runOnFunction(Function &FI); |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 45 | typedef std::map<const MachineInstr*, unsigned> InstructionKey; |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 46 | private: |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 47 | MappingInfo *currentOutputMap; |
| 48 | std::map<Function *, unsigned> Fkey; // Function # for all functions. |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 49 | bool doInitialization(Module &M); |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 50 | void create_BB_to_MInumber_Key(Function &FI, InstructionKey &key); |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 51 | void buildBBMIMap (Function &FI, MappingInfo &Map); |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 52 | void writeNumber(unsigned X); |
| 53 | void selectOutputMap (MappingInfo &m) { currentOutputMap = &m; } |
| 54 | void outByte (unsigned char b) { currentOutputMap->outByte (b); } |
Brian Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 55 | bool doFinalization (Module &M); |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 56 | }; |
| 57 | } |
| 58 | |
Brian Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 59 | /// getMappingInfoAsmPrinterPass - Static factory method: returns a new |
| 60 | /// MappingInfoAsmPrinter Pass object, which uses OUT as its output |
| 61 | /// stream for assembly output. |
| 62 | /// |
Chris Lattner | b12914b | 2004-09-20 04:48:05 +0000 | [diff] [blame] | 63 | ModulePass *getMappingInfoAsmPrinterPass(std::ostream &out){ |
| 64 | return new MappingInfoAsmPrinter(out); |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 65 | } |
| 66 | |
Brian Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 67 | /// runOnFunction - Builds up the maps for the given function FI and then |
Brian Gaeke | fc97c8b | 2003-06-03 19:30:15 +0000 | [diff] [blame] | 68 | /// writes them out as assembly code to the current output stream OUT. |
Brian Gaeke | e14ccaf | 2003-06-03 07:56:05 +0000 | [diff] [blame] | 69 | /// This is an entry point to the pass, called by the PassManager. |
Brian Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 70 | /// |
| 71 | bool MappingInfoAsmPrinter::runOnFunction(Function &FI) { |
Brian Gaeke | fc97c8b | 2003-06-03 19:30:15 +0000 | [diff] [blame] | 72 | unsigned num = Fkey[&FI]; // Function number for the current function. |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 73 | |
Brian Gaeke | 849c7b5 | 2004-10-19 05:15:21 +0000 | [diff] [blame] | 74 | // Create an object to hold the map, then build the map. |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 75 | MappingInfo BBMIMap ("BB TO MI MAP", "BBMIMap", num); |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 76 | buildBBMIMap (FI, BBMIMap); |
| 77 | |
Brian Gaeke | fc97c8b | 2003-06-03 19:30:15 +0000 | [diff] [blame] | 78 | // Now, write out the maps. |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 79 | BBMIMap.dumpAssembly (Out); |
Brian Gaeke | fc97c8b | 2003-06-03 19:30:15 +0000 | [diff] [blame] | 80 | |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 81 | return false; |
| 82 | } |
| 83 | |
Brian Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 84 | /// writeNumber - Write out the number X as a sequence of .byte |
Brian Gaeke | fc97c8b | 2003-06-03 19:30:15 +0000 | [diff] [blame] | 85 | /// directives to the current output stream Out. This method performs a |
| 86 | /// run-length encoding of the unsigned integers X that are output. |
Brian Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 87 | /// |
| 88 | void MappingInfoAsmPrinter::writeNumber(unsigned X) { |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 89 | unsigned i=0; |
| 90 | do { |
| 91 | unsigned tmp = X & 127; |
| 92 | X >>= 7; |
| 93 | if (X) tmp |= 128; |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 94 | outByte (tmp); |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 95 | ++i; |
| 96 | } while(X); |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 97 | } |
| 98 | |
Brian Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 99 | /// doInitialization - Assign a number to each Function, as follows: |
Brian Gaeke | e14ccaf | 2003-06-03 07:56:05 +0000 | [diff] [blame] | 100 | /// 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 Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 105 | /// |
| 106 | bool MappingInfoAsmPrinter::doInitialization(Module &M) { |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 107 | unsigned i = 0; |
Brian Gaeke | e14ccaf | 2003-06-03 07:56:05 +0000 | [diff] [blame] | 108 | for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) { |
| 109 | if (FI->isExternal()) continue; |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 110 | Fkey[FI] = i; |
| 111 | ++i; |
| 112 | } |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 113 | return false; // Success. |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 114 | } |
Brian Gaeke | e14ccaf | 2003-06-03 07:56:05 +0000 | [diff] [blame] | 115 | |
| 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 Brukman | cf00c4a | 2003-10-10 17:57:28 +0000 | [diff] [blame] | 121 | /// it contains. The side-effect of this method is to fill in the parameter |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 122 | /// KEY with the mapping of MachineBasicBlocks to numbers. KEY |
Brian Gaeke | e14ccaf | 2003-06-03 07:56:05 +0000 | [diff] [blame] | 123 | /// is keyed on MachineInstrs, so each MachineBasicBlock is represented |
| 124 | /// therein by its first MachineInstr. |
Brian Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 125 | /// |
| 126 | void MappingInfoAsmPrinter::create_BB_to_MInumber_Key(Function &FI, |
Brian Gaeke | 849c7b5 | 2004-10-19 05:15:21 +0000 | [diff] [blame] | 127 | InstructionKey &key) { |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 128 | unsigned i = 0; |
Misha Brukman | b7551ef | 2002-10-28 20:00:31 +0000 | [diff] [blame] | 129 | MachineFunction &MF = MachineFunction::get(&FI); |
| 130 | for (MachineFunction::iterator BI = MF.begin(), BE = MF.end(); |
| 131 | BI != BE; ++BI) { |
| 132 | MachineBasicBlock &miBB = *BI; |
Alkis Evlogimenos | c0b9dc5 | 2004-02-12 02:27:10 +0000 | [diff] [blame] | 133 | key[&miBB.front()] = i; |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 134 | i = i+(miBB.size()); |
| 135 | } |
| 136 | } |
| 137 | |
Brian Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 138 | /// buildBBMIMap - Build the BB TO MI MAP for the function FI, |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 139 | /// and save it into the parameter MAP. |
Brian Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 140 | /// |
| 141 | void MappingInfoAsmPrinter::buildBBMIMap(Function &FI, MappingInfo &Map) { |
Misha Brukman | b7551ef | 2002-10-28 20:00:31 +0000 | [diff] [blame] | 142 | unsigned bb = 0; |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 143 | |
| 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 Brukman | b7551ef | 2002-10-28 20:00:31 +0000 | [diff] [blame] | 149 | 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 Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 153 | writeNumber(bb); |
Alkis Evlogimenos | c0b9dc5 | 2004-02-12 02:27:10 +0000 | [diff] [blame] | 154 | writeNumber(BBkey[&miBB.front()]); |
Anand Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 155 | writeNumber(miBB.size()); |
| 156 | } |
| 157 | } |
| 158 | |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 159 | void 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 Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 164 | static void writePrologue (std::ostream &Out, const std::string &comment, |
| 165 | const std::string &symName) { |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 166 | // Prologue: |
Brian Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 167 | // Output a comment describing the object. |
Brian Gaeke | aeab1e1 | 2003-06-04 22:07:12 +0000 | [diff] [blame] | 168 | 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 Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 171 | // 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 Shukla | b85d265 | 2002-08-27 22:47:33 +0000 | [diff] [blame] | 175 | } |
Brian Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 176 | |
| 177 | static 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 | |
| 186 | void 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 | /// |
| 200 | bool 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 Gaeke | 866dc1d | 2003-09-18 17:37:25 +0000 | [diff] [blame] | 213 | return false; |
| 214 | } |
| 215 | |
Brian Gaeke | d0fde30 | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 216 | } // End llvm namespace |