X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FStackColoring.cpp;h=1cbee843a125e24b692783532b2476241c0fa1b3;hb=dfa4cecb1e549d96f800f7ebc793a342d8df1244;hp=832d4d1ca5d3f2758bbe096917dd6e74114c902e;hpb=faf31d01db913b477b749c9f11f18a9471c0a672;p=oota-llvm.git diff --git a/lib/CodeGen/StackColoring.cpp b/lib/CodeGen/StackColoring.cpp index 832d4d1ca5d..1cbee843a12 100644 --- a/lib/CodeGen/StackColoring.cpp +++ b/lib/CodeGen/StackColoring.cpp @@ -48,6 +48,7 @@ #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/SlotIndexes.h" #include "llvm/DebugInfo.h" +#include "llvm/Instructions.h" #include "llvm/MC/MCInstrItineraries.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" @@ -62,10 +63,14 @@ DisableColoring("no-stack-coloring", cl::init(false), cl::Hidden, cl::desc("Disable stack coloring")); +/// The user may write code that uses allocas outside of the declared lifetime +/// zone. This can happen when the user returns a reference to a local +/// data-structure. We can detect these cases and decide not to optimize the +/// code. If this flag is enabled, we try to save the user. static cl::opt -CheckEscapedAllocas("stack-coloring-check-escaped", - cl::init(true), cl::Hidden, - cl::desc("Look for allocas which escaped the lifetime region")); +ProtectFromEscapedAllocas("protect-from-escaped-allocas", + cl::init(false), cl::Hidden, + cl::desc("Do not optimize lifetime zones that are broken")); STATISTIC(NumMarkerSeen, "Number of lifetime markers found."); STATISTIC(StackSpaceSaved, "Number of bytes saved due to merging slots."); @@ -256,7 +261,7 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) { MarkersFound++; - const Value *Allocation = MFI->getObjectAllocation(Slot); + const AllocaInst *Allocation = MFI->getObjectAllocation(Slot); if (Allocation) { DEBUG(dbgs()<<"Found a lifetime marker for slot #"<getName()<<"\n"); @@ -476,11 +481,11 @@ void StackColoring::remapInstructions(DenseMap &SlotRemap) { } // Keep a list of *allocas* which need to be remapped. - DenseMap Allocas; + DenseMap Allocas; for (DenseMap::iterator it = SlotRemap.begin(), e = SlotRemap.end(); it != e; ++it) { - const Value *From = MFI->getObjectAllocation(it->first); - const Value *To = MFI->getObjectAllocation(it->second); + const AllocaInst *From = MFI->getObjectAllocation(it->first); + const AllocaInst *To = MFI->getObjectAllocation(it->second); assert(To && From && "Invalid allocation object"); Allocas[From] = To; } @@ -510,10 +515,17 @@ void StackColoring::remapInstructions(DenseMap &SlotRemap) { V = GetUnderlyingObject(V); // If we did not find one, or if the one that we found is not in our // map, then move on. - if (!V || !Allocas.count(V)) + if (!V || !isa(V)) { + // Clear mem operand since we don't know for sure that it doesn't + // alias a merged alloca. + MMO->setValue(0); + continue; + } + const AllocaInst *AI= cast(V); + if (!Allocas.count(AI)) continue; - MMO->setValue(Allocas[V]); + MMO->setValue(Allocas[AI]); FixedMemOp++; } @@ -536,13 +548,15 @@ void StackColoring::remapInstructions(DenseMap &SlotRemap) { // In a debug build, check that the instruction that we are modifying is // inside the expected live range. If the instruction is not inside // the calculated range then it means that the alloca usage moved - // outside of the lifetime markers. + // outside of the lifetime markers, or that the user has a bug. // NOTE: Alloca address calculations which happen outside the lifetime // zone are are okay, despite the fact that we don't have a good way // for validating all of the usages of the calculation. #ifndef NDEBUG bool TouchesMemory = I->mayLoad() || I->mayStore(); - if (!I->isDebugValue() && TouchesMemory) { + // If we *don't* protect the user from escaped allocas, don't bother + // validating the instructions. + if (!I->isDebugValue() && TouchesMemory && ProtectFromEscapedAllocas) { SlotIndex Index = Indexes->getInstructionIndex(I); LiveInterval *Interval = Intervals[FromSlot]; assert(Interval->find(Index) != Interval->end() && @@ -685,7 +699,7 @@ bool StackColoring::runOnMachineFunction(MachineFunction &Func) { // Search for allocas which are used outside of the declared lifetime // markers. - if (CheckEscapedAllocas) + if (ProtectFromEscapedAllocas) removeInvalidSlotRanges(); // Maps old slots to new slots.