From c4bcc778a8dcc385b129852c9aa1c712d042ad63 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Tue, 20 Jul 2010 07:41:44 +0000 Subject: [PATCH] Switched to rendering after allocation (but before rewriting) in PBQP. Updated renderer to use allocation information from VirtRegMap (if available) to render spilled intervals differently. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@108815 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/RegAllocPBQP.cpp | 5 +- lib/CodeGen/RenderMachineFunction.cpp | 90 ++++++++++++++++++--------- lib/CodeGen/RenderMachineFunction.h | 20 ++++-- 3 files changed, 77 insertions(+), 38 deletions(-) diff --git a/lib/CodeGen/RegAllocPBQP.cpp b/lib/CodeGen/RegAllocPBQP.cpp index 7b21ec3c4fc..594618891de 100644 --- a/lib/CodeGen/RegAllocPBQP.cpp +++ b/lib/CodeGen/RegAllocPBQP.cpp @@ -865,11 +865,10 @@ bool PBQPRegAlloc::runOnMachineFunction(MachineFunction &MF) { lis = &getAnalysis(); lss = &getAnalysis(); loopInfo = &getAnalysis(); + RenderMachineFunction *rmf = &getAnalysis(); vrm = &getAnalysis(); - RenderMachineFunction *rmf = &getAnalysis(); - rmf->renderMachineFunction("Prior to PBQP register allocation."); DEBUG(dbgs() << "PBQP Register Allocating for " << mf->getFunction()->getName() << "\n"); @@ -907,6 +906,8 @@ bool PBQPRegAlloc::runOnMachineFunction(MachineFunction &MF) { // Finalise allocation, allocate empty ranges. finalizeAlloc(); + rmf->renderMachineFunction("After PBQP register allocation.", vrm); + vregIntervalsToAlloc.clear(); emptyVRegIntervals.clear(); li2Node.clear(); diff --git a/lib/CodeGen/RenderMachineFunction.cpp b/lib/CodeGen/RenderMachineFunction.cpp index 6520449a79a..2095e2dbe9c 100644 --- a/lib/CodeGen/RenderMachineFunction.cpp +++ b/lib/CodeGen/RenderMachineFunction.cpp @@ -11,6 +11,8 @@ #include "RenderMachineFunction.h" +#include "VirtRegMap.h" + #include "llvm/Function.h" #include "llvm/Module.h" #include "llvm/ADT/SmallVector.h" @@ -511,6 +513,50 @@ namespace llvm { return r; } + RenderMachineFunction::LiveState + RenderMachineFunction::getLiveStateAt(const LiveInterval *li, + SlotIndex i) const { + const MachineInstr *mi = sis->getInstructionFromIndex(i); + + if (li->liveAt(i)) { + if (mi == 0) { + if (vrm == 0 || + (vrm->getStackSlot(li->reg) == VirtRegMap::NO_STACK_SLOT)) { + return AliveReg; + } else { + return AliveStack; + } + } else { + if (i.getSlot() == SlotIndex::DEF && + mi->definesRegister(li->reg, tri)) { + return Defined; + } else if (i.getSlot() == SlotIndex::USE && + mi->readsRegister(li->reg)) { + return Used; + } else { + if (vrm == 0 || + (vrm->getStackSlot(li->reg) == VirtRegMap::NO_STACK_SLOT)) { + return AliveReg; + } else { + return AliveStack; + } + } + } + } + return Dead; + } + + /// \brief Render a machine instruction. + template + void RenderMachineFunction::renderMachineInstr(OStream &os, + const MachineInstr *mi) const { + std::string s; + raw_string_ostream oss(s); + oss << *mi; + + os << escapeChars(oss.str()); + } + template void RenderMachineFunction::renderVertical(const std::string &indent, OStream &os, @@ -557,7 +603,8 @@ namespace llvm { << indent << " table.code td.l-na { background-color: #ffffff; }\n" << indent << " table.code td.l-def { background-color: #ff0000; }\n" << indent << " table.code td.l-use { background-color: #ffff00; }\n" - << indent << " table.code td.l-sa { background-color: #000000; }\n" + << indent << " table.code td.l-sar { background-color: #000000; }\n" + << indent << " table.code td.l-sas { background-color: #770000; }\n" << indent << " table.code th { border-width: 0px; " "border-style: solid; }\n" << indent << "\n"; @@ -663,7 +710,9 @@ namespace llvm { if (i == sis->getMBBStartIdx(mbb)) { os << indent << " BB#" << mbb->getNumber() << ": \n"; } else if (mi != 0) { - os << indent << "   " << escapeChars(mi) << "\n"; + os << indent << "   "; + renderMachineInstr(os, mi); + os << "\n"; } else { os << indent << "  \n"; } @@ -706,22 +755,13 @@ namespace llvm { liItr != liEnd; ++liItr) { const LiveInterval *li = *liItr; os << indent << " liveAt(i)) { - if (mi == 0) { - os << "l-sa"; - } else { - if (i.getSlot() == SlotIndex::DEF && - mi->definesRegister(li->reg, tri)) { - os << "l-def"; - } else if (i.getSlot() == SlotIndex::USE && - mi->readsRegister(li->reg)) { - os << "l-use"; - } else { - os << "l-sa"; - } - } - } else { - os << "l-na"; + switch (getLiveStateAt(li, i)) { + case Dead: os << "l-na"; break; + case Defined: os << "l-def"; break; + case Used: os << "l-use"; break; + case AliveReg: os << "l-sar"; break; + case AliveStack: os << "l-sas"; break; + default: assert(false && "Unrecognised live state."); break; } os << "\">\n"; } @@ -797,10 +837,12 @@ namespace llvm { void RenderMachineFunction::renderMachineFunction( const char *renderContextStr, + const VirtRegMap *vrm, const char *renderSuffix) { if (!ro.shouldRenderCurrentMachineFunction()) return; + this->vrm = vrm; trei.reset(); std::string rpFileName(mf->getFunction()->getName().str() + @@ -815,20 +857,8 @@ namespace llvm { ro.resetRenderSpecificOptions(); } - void RenderMachineFunction::setupRenderingOptions() { - - } - std::string RenderMachineFunction::escapeChars(const std::string &s) const { return escapeChars(s.begin(), s.end()); } - std::string RenderMachineFunction::escapeChars(const MachineInstr *mi) const { - std::string s; - raw_string_ostream os(s); - os << *mi; - std::string s2 = os.str(); - return escapeChars(s2); - } - } diff --git a/lib/CodeGen/RenderMachineFunction.h b/lib/CodeGen/RenderMachineFunction.h index b2ccc3e1fa4..743938d9edb 100644 --- a/lib/CodeGen/RenderMachineFunction.h +++ b/lib/CodeGen/RenderMachineFunction.h @@ -30,7 +30,7 @@ namespace llvm { class MachineRegisterInfo; class TargetRegisterClass; class TargetRegisterInfo; - + class VirtRegMap; /// \brief Provide extra information about the physical and virtual registers /// in the function being compiled. @@ -212,10 +212,14 @@ namespace llvm { /// codegen pipeline) this function was rendered /// from. Set it to something like /// "Pre-register-allocation". + /// @param vrm If non-null the VRM will be queried to determine + /// whether a virtual register was allocated to a + /// physical register or spilled. /// @param renderFilePrefix This string will be appended to the function /// name (before the output file suffix) to enable /// multiple renderings from the same function. void renderMachineFunction(const char *renderContextStr, + const VirtRegMap *vrm = 0, const char *renderSuffix = 0); private: @@ -227,19 +231,26 @@ namespace llvm { const TargetRegisterInfo *tri; LiveIntervals *lis; SlotIndexes *sis; + const VirtRegMap *vrm; TargetRegisterExtraInfo trei; MFRenderingOptions ro; - // ---------- Utility functions ---------- + // Utilities. + typedef enum { Dead, Defined, Used, AliveReg, AliveStack } LiveState; - void setupRenderingOptions(); + LiveState getLiveStateAt(const LiveInterval *li, SlotIndex i) const; // ---------- Rendering methods ---------- template std::string escapeChars(Iterator sBegin, Iterator sEnd) const; + /// \brief Render a machine instruction. + template + void renderMachineInstr(OStream &os, + const MachineInstr *mi) const; + /// \brief Render vertical text. template void renderVertical(const std::string &indent, @@ -282,9 +293,6 @@ namespace llvm { const char * const renderContextStr) const; std::string escapeChars(const std::string &s) const; - - std::string escapeChars(const MachineInstr *mi) const; - }; } -- 2.34.1