//===- MappingInfo.cpp - create LLVM info and output to .s file ---------===//
//
-// This file contains a FunctionPass called MappingInfo,
+// This file contains a FunctionPass called MappingInfoAsmPrinter,
// which creates two maps: one between LLVM Instructions and MachineInstrs
// (the "LLVM I TO MI MAP"), and another between MachineBasicBlocks and
// MachineInstrs (the "BB TO MI MAP").
#include "llvm/Module.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineCodeForInstruction.h"
+#include "Support/StringExtras.h"
namespace {
- class MappingInfoCollector : public FunctionPass {
+ class MappingInfoAsmPrinter : public FunctionPass {
std::ostream &Out;
public:
- MappingInfoCollector(std::ostream &out) : Out(out){}
+ MappingInfoAsmPrinter(std::ostream &out) : Out(out){}
const char *getPassName () const { return "Instr. Mapping Info Collector"; }
bool runOnFunction(Function &FI);
typedef std::map<const MachineInstr*, unsigned> InstructionKey;
void writeNumber(unsigned X);
void selectOutputMap (MappingInfo &m) { currentOutputMap = &m; }
void outByte (unsigned char b) { currentOutputMap->outByte (b); }
+ bool doFinalization (Module &M);
};
}
-/// getMappingInfoCollector -- Static factory method: returns a new
-/// MappingInfoCollector Pass object, which uses OUT as its
-/// output stream for assembly output.
-Pass *getMappingInfoCollector(std::ostream &out){
- return (new MappingInfoCollector(out));
+/// getMappingInfoAsmPrinterPass - Static factory method: returns a new
+/// MappingInfoAsmPrinter Pass object, which uses OUT as its output
+/// stream for assembly output.
+///
+Pass *getMappingInfoAsmPrinterPass(std::ostream &out){
+ return (new MappingInfoAsmPrinter(out));
}
-/// runOnFunction -- Builds up the maps for the given function FI and then
+/// runOnFunction - Builds up the maps for the given function FI and then
/// writes them out as assembly code to the current output stream OUT.
/// This is an entry point to the pass, called by the PassManager.
-bool MappingInfoCollector::runOnFunction(Function &FI) {
+///
+bool MappingInfoAsmPrinter::runOnFunction(Function &FI) {
unsigned num = Fkey[&FI]; // Function number for the current function.
// Create objects to hold the maps.
return false;
}
-/// writeNumber -- Write out the number X as a sequence of .byte
+/// writeNumber - Write out the number X as a sequence of .byte
/// directives to the current output stream Out. This method performs a
/// run-length encoding of the unsigned integers X that are output.
-void MappingInfoCollector::writeNumber(unsigned X) {
+///
+void MappingInfoAsmPrinter::writeNumber(unsigned X) {
unsigned i=0;
do {
unsigned tmp = X & 127;
} while(X);
}
-/// doInitialization -- Assign a number to each Function, as follows:
+/// doInitialization - Assign a number to each Function, as follows:
/// Functions are numbered starting at 0 at the begin() of each Module.
/// Functions which are External (and thus have 0 basic blocks) are not
/// inserted into the maps, and are not assigned a number. The side-effect
/// of this method is to fill in Fkey to contain the mapping from Functions
/// to numbers. (This method is called automatically by the PassManager.)
-bool MappingInfoCollector::doInitialization(Module &M) {
+///
+bool MappingInfoAsmPrinter::doInitialization(Module &M) {
unsigned i = 0;
for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) {
if (FI->isExternal()) continue;
/// KEY with the mapping of MachineBasicBlocks to numbers. KEY
/// is keyed on MachineInstrs, so each MachineBasicBlock is represented
/// therein by its first MachineInstr.
-void MappingInfoCollector::create_BB_to_MInumber_Key(Function &FI,
+///
+void MappingInfoAsmPrinter::create_BB_to_MInumber_Key(Function &FI,
InstructionKey &key) {
unsigned i = 0;
MachineFunction &MF = MachineFunction::get(&FI);
}
}
-/// create_MI_to_number_Key -- Assign a number to each MachineInstr
+/// create_MI_to_number_Key - Assign a number to each MachineInstr
/// in the given Function with respect to its enclosing MachineBasicBlock, as
/// follows: Numberings start at 0 in each MachineBasicBlock. MachineInstrs
/// are numbered from begin() to end() in their MachineBasicBlock. Each
/// MachineInstr is numbered, then the numbering is incremented by 1. The
/// side-effect of this method is to fill in the parameter KEY
/// with the mapping from MachineInstrs to numbers.
-void MappingInfoCollector::create_MI_to_number_Key(Function &FI,
+///
+void MappingInfoAsmPrinter::create_MI_to_number_Key(Function &FI,
InstructionKey &key) {
MachineFunction &MF = MachineFunction::get(&FI);
for (MachineFunction::iterator BI=MF.begin(), BE=MF.end(); BI != BE; ++BI) {
}
}
-/// buildBBMIMap -- Build the BB TO MI MAP for the function FI,
+/// buildBBMIMap - Build the BB TO MI MAP for the function FI,
/// and save it into the parameter MAP.
-void MappingInfoCollector::buildBBMIMap(Function &FI, MappingInfo &Map) {
+///
+void MappingInfoAsmPrinter::buildBBMIMap(Function &FI, MappingInfo &Map) {
unsigned bb = 0;
// First build temporary table used to write out the map.
}
}
-/// buildLMIMap -- Build the LLVM I TO MI MAP for the function FI,
+/// buildLMIMap - Build the LLVM I TO MI MAP for the function FI,
/// and save it into the parameter MAP.
-void MappingInfoCollector::buildLMIMap(Function &FI, MappingInfo &Map) {
+///
+void MappingInfoAsmPrinter::buildLMIMap(Function &FI, MappingInfo &Map) {
unsigned bb = 0;
// First build temporary table used to write out the map.
InstructionKey MIkey;
Out << ".byte " << (int)*i << "\n";
}
-void MappingInfo::dumpAssembly (std::ostream &Out) {
+static void writePrologue (std::ostream &Out, const std::string &comment,
+ const std::string &symName) {
// Prologue:
- // Output a comment describing the map.
+ // Output a comment describing the object.
Out << "!" << comment << "\n";
// Switch the current section to .rodata in the assembly output:
Out << "\t.section \".rodata\"\n\t.align 8\n";
- // Output a global symbol naming the map:
- Out << "\t.global " << symbolPrefix << functionNumber << "\n";
- Out << "\t.type " << symbolPrefix << functionNumber << ",#object\n";
- Out << symbolPrefix << functionNumber << ":\n";
- // Output a word containing the length of the map:
- Out << "\t.word .end_" << symbolPrefix << functionNumber << "-"
- << symbolPrefix << functionNumber << "\n";
-
- // Output the map data itself:
- bytes.dumpAssembly (Out);
+ // Output a global symbol naming the object:
+ Out << "\t.global " << symName << "\n";
+ Out << "\t.type " << symName << ",#object\n";
+ Out << symName << ":\n";
+}
+static void writeEpilogue (std::ostream &Out, const std::string &symName) {
// Epilogue:
- // Output a local symbol marking the end of the map:
- Out << ".end_" << symbolPrefix << functionNumber << ":\n";
- // Output size directive giving the size of the map:
- Out << "\t.size " << symbolPrefix << functionNumber << ", .end_"
- << symbolPrefix << functionNumber << "-" << symbolPrefix
- << functionNumber << "\n\n";
+ // Output a local symbol marking the end of the object:
+ Out << ".end_" << symName << ":\n";
+ // Output size directive giving the size of the object:
+ Out << "\t.size " << symName << ", .end_" << symName << "-" << symName
+ << "\n";
+}
+
+void MappingInfo::dumpAssembly (std::ostream &Out) {
+ const std::string &name (symbolPrefix + utostr (functionNumber));
+ writePrologue (Out, comment, name);
+ // The LMIMap and BBMIMap are supposed to start with a length word:
+ Out << "\t.word .end_" << name << "-" << name << "\n";
+ bytes.dumpAssembly (Out);
+ writeEpilogue (Out, name);
+}
+
+/// doFinalization - This method writes out two tables, named
+/// FunctionBB and FunctionLI, which map Function numbers (as in
+/// doInitialization) to the BBMIMap and LMIMap tables. (This used to
+/// be the "FunctionInfo" pass.)
+///
+bool MappingInfoAsmPrinter::doFinalization (Module &M) {
+ unsigned f;
+
+ writePrologue(Out, "FUNCTION TO BB MAP", "FunctionBB");
+ f=0;
+ for(Module::iterator FI = M.begin (), FE = M.end (); FE != FI; ++FI) {
+ if (FI->isExternal ())
+ continue;
+ Out << "\t.xword BBMIMap" << f << "\n";
+ ++f;
+ }
+ writeEpilogue(Out, "FunctionBB");
+
+ writePrologue(Out, "FUNCTION TO LI MAP", "FunctionLI");
+ f=0;
+ for(Module::iterator FI = M.begin (), FE = M.end (); FE != FI; ++FI) {
+ if (FI->isExternal ())
+ continue;
+ Out << "\t.xword LMIMap" << f << "\n";
+ ++f;
+ }
+ writeEpilogue(Out, "FunctionLI");
+
+ return false;
}
+