X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FMachineModuleInfo.cpp;h=72a9450dcb405e7d53cf4abfc8001088c93d07dd;hb=0220ba7995236accae6ac009a2700871fc17007d;hp=72fb9fd987d9981d325f321a9c93c9e669d42111;hpb=a34ec2290fa441d312ac33a61e6ec6029259bdef;p=oota-llvm.git diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp index 72fb9fd987d..72a9450dcb4 100644 --- a/lib/CodeGen/MachineModuleInfo.cpp +++ b/lib/CodeGen/MachineModuleInfo.cpp @@ -10,6 +10,11 @@ #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/GlobalVariable.h" +#include "llvm/Intrinsics.h" +#include "llvm/Instructions.h" +#include "llvm/Module.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFunction.h" @@ -17,11 +22,7 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/DerivedTypes.h" -#include "llvm/GlobalVariable.h" -#include "llvm/Intrinsics.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" using namespace llvm; @@ -29,38 +30,144 @@ using namespace llvm::dwarf; // Handle the Pass registration stuff necessary to use TargetData's. static RegisterPass -X("machinemoduleinfo", "Module Information"); +X("machinemoduleinfo", "Machine Module Information"); char MachineModuleInfo::ID = 0; // Out of line virtual method. MachineModuleInfoImpl::~MachineModuleInfoImpl() {} +namespace llvm { +class MMIAddrLabelMapCallbackPtr : CallbackVH { + MMIAddrLabelMap *Map; +public: + MMIAddrLabelMapCallbackPtr() : Map(0) {} + MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V), Map(0) {} + + void setMap(MMIAddrLabelMap *map) { Map = map; } + + virtual void deleted(); + virtual void allUsesReplacedWith(Value *V2); +}; + +class MMIAddrLabelMap { + MCContext &Context; + struct AddrLabelSymEntry { + MCSymbol *Sym; + unsigned Index; + }; + + DenseMap, AddrLabelSymEntry> AddrLabelSymbols; + + std::vector BBCallbacks; +public: + + MMIAddrLabelMap(MCContext &context) : Context(context) {} + + MCSymbol *getAddrLabelSymbol(BasicBlock *BB); + void UpdateForDeletedBlock(BasicBlock *BB); + void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New); +}; +} + +MCSymbol *MMIAddrLabelMap::getAddrLabelSymbol(BasicBlock *BB) { + assert(BB->hasAddressTaken() && + "Shouldn't get label for block without address taken"); + AddrLabelSymEntry &Entry = AddrLabelSymbols[BB]; + + // If we already had an entry for this block, just return it. + if (Entry.Sym) return Entry.Sym; + + // Otherwise, this is a new entry, create a new symbol for it and add an + // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd. + BBCallbacks.push_back(BB); + BBCallbacks.back().setMap(this); + Entry.Index = BBCallbacks.size()-1; + return Entry.Sym = Context.CreateTempSymbol(); +} + +void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { + // If the block got deleted, there is no need for the symbol. If the symbol + // was already emitted, we can just forget about it, otherwise we need to + // queue it up for later emission when the function is output. + AddrLabelSymEntry Entry = AddrLabelSymbols[BB]; + AddrLabelSymbols.erase(BB); + assert(Entry.Sym && "Didn't have a symbol, why a callback?"); + BBCallbacks[Entry.Index] = 0; // Clear the callback. + + if (Entry.Sym->isDefined()) + return; + + // If the block is not yet defined, we need to emit it at the end of the + // function. + assert(0 && "Case not handled yet!"); + abort(); +} + +void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) { + // Get the entry for the RAUW'd block and remove it from our map. + AddrLabelSymEntry OldEntry = AddrLabelSymbols[Old]; + AddrLabelSymbols.erase(Old); + assert(OldEntry.Sym && "Didn't have a symbol, why a callback?"); + + // If New is not address taken, just move our symbol over to it. + if (!AddrLabelSymbols.count(New)) { + BBCallbacks[OldEntry.Index] = New; // Update the callback. + AddrLabelSymbols[New] = OldEntry; // Set New's entry. + } else { + assert(0 && "Case not handled yet!"); + abort(); + } +} + + +void MMIAddrLabelMapCallbackPtr::deleted() { + Map->UpdateForDeletedBlock(cast(getValPtr())); +} + +void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) { + Map->UpdateForRAUWBlock(cast(getValPtr()), cast(V2)); +} + + //===----------------------------------------------------------------------===// -MachineModuleInfo::MachineModuleInfo() -: ImmutablePass(&ID) -, ObjFileMMI(0) -, CurCallSite(0) -, CallsEHReturn(0) -, CallsUnwindInit(0) -, DbgInfoAvailable(false) { +MachineModuleInfo::MachineModuleInfo(const MCAsmInfo &MAI) +: ImmutablePass(&ID), Context(MAI), + ObjFileMMI(0), + CurCallSite(0), CallsEHReturn(0), CallsUnwindInit(0), DbgInfoAvailable(false){ // Always emit some info, by default "no personality" info. Personalities.push_back(NULL); + AddrLabelSymbols = 0; +} + +MachineModuleInfo::MachineModuleInfo() +: ImmutablePass(&ID), Context(*(MCAsmInfo*)0) { + assert(0 && "This MachineModuleInfo constructor should never be called, MMI " + "should always be explicitly constructed by LLVMTargetMachine"); + abort(); } MachineModuleInfo::~MachineModuleInfo() { delete ObjFileMMI; + + // FIXME: Why isn't doFinalization being called?? + //assert(AddrLabelSymbols == 0 && "doFinalization not called"); + delete AddrLabelSymbols; + AddrLabelSymbols = 0; } /// doInitialization - Initialize the state for a new module. /// bool MachineModuleInfo::doInitialization() { + assert(AddrLabelSymbols == 0 && "Improperly initialized"); return false; } /// doFinalization - Tear down the state after completion of a module. /// bool MachineModuleInfo::doFinalization() { + delete AddrLabelSymbols; + AddrLabelSymbols = 0; return false; } @@ -99,7 +206,21 @@ void MachineModuleInfo::AnalyzeModule(Module &M) { UsedFunctions.insert(F); } -//===-EH-------------------------------------------------------------------===// +//===- Address of Block Management ----------------------------------------===// + + +/// getAddrLabelSymbol - Return the symbol to be used for the specified basic +/// block when its address is taken. This cannot be its normal LBB label +/// because the block may be accessed outside its containing function. +MCSymbol *MachineModuleInfo::getAddrLabelSymbol(const BasicBlock *BB) { + // Lazily create AddrLabelSymbols. + if (AddrLabelSymbols == 0) + AddrLabelSymbols = new MMIAddrLabelMap(Context); + return AddrLabelSymbols->getAddrLabelSymbol(const_cast(BB)); +} + + +//===- EH -----------------------------------------------------------------===// /// getOrCreateLandingPadInfo - Find or create an LandingPadInfo for the /// specified MachineBasicBlock. @@ -119,7 +240,7 @@ LandingPadInfo &MachineModuleInfo::getOrCreateLandingPadInfo /// addInvoke - Provide the begin and end labels of an invoke style call and /// associate it with a try landing pad block. void MachineModuleInfo::addInvoke(MachineBasicBlock *LandingPad, - unsigned BeginLabel, unsigned EndLabel) { + MCSymbol *BeginLabel, MCSymbol *EndLabel) { LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad); LP.BeginLabels.push_back(BeginLabel); LP.EndLabels.push_back(EndLabel); @@ -127,8 +248,8 @@ void MachineModuleInfo::addInvoke(MachineBasicBlock *LandingPad, /// addLandingPad - Provide the label of a try LandingPad block. /// -unsigned MachineModuleInfo::addLandingPad(MachineBasicBlock *LandingPad) { - unsigned LandingPadLabel = NextLabelID(); +MCSymbol *MachineModuleInfo::addLandingPad(MachineBasicBlock *LandingPad) { + MCSymbol *LandingPadLabel = Context.CreateTempSymbol(); LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad); LP.LandingPadLabel = LandingPadLabel; return LandingPadLabel; @@ -185,7 +306,7 @@ void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) { void MachineModuleInfo::TidyLandingPads() { for (unsigned i = 0; i != LandingPads.size(); ) { LandingPadInfo &LandingPad = LandingPads[i]; - if (isLabelDeleted(LandingPad.LandingPadLabel)) + if (LandingPad.LandingPadLabel && !LandingPad.LandingPadLabel->isDefined()) LandingPad.LandingPadLabel = 0; // Special case: we *should* emit LPs with null LP MBB. This indicates @@ -195,16 +316,14 @@ void MachineModuleInfo::TidyLandingPads() { continue; } - for (unsigned j=0; j != LandingPads[i].BeginLabels.size(); ) { - unsigned BeginLabel = LandingPad.BeginLabels[j]; - unsigned EndLabel = LandingPad.EndLabels[j]; - if (isLabelDeleted(BeginLabel) || isLabelDeleted(EndLabel)) { - LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j); - LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j); - continue; - } - - ++j; + for (unsigned j = 0, e = LandingPads[i].BeginLabels.size(); j != e; ++j) { + MCSymbol *BeginLabel = LandingPad.BeginLabels[j]; + MCSymbol *EndLabel = LandingPad.EndLabels[j]; + if (BeginLabel->isDefined() && EndLabel->isDefined()) continue; + + LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j); + LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j); + --j, --e; } // Remove landing pads with no try-ranges. @@ -218,7 +337,6 @@ void MachineModuleInfo::TidyLandingPads() { if (!LandingPad.LandingPadBlock || (LandingPad.TypeIds.size() == 1 && !LandingPad.TypeIds[0])) LandingPad.TypeIds.clear(); - ++i; } }