mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-01 00:33:09 +00:00
Temporarily revert r187323 until I update SSAUpdater to match mem2reg.
I forgot that we had two totally independent things here. :: sigh :: git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187327 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
dc8a318f44
commit
65f12f1d05
@ -197,18 +197,6 @@ public:
|
||||
/// \brief Construct the slices of a particular alloca.
|
||||
AllocaSlices(const DataLayout &DL, AllocaInst &AI);
|
||||
|
||||
/// \brief Whether we determined during the trivial analysis of the alloca
|
||||
/// that it was immediately promotable with mem2reg.
|
||||
bool isAllocaPromotable() const { return IsAllocaPromotable; }
|
||||
|
||||
/// \brief A list of directly stored values when \c isAllocaPromotable is
|
||||
/// true.
|
||||
///
|
||||
/// The contents are undefined if the alloca is not trivially promotable.
|
||||
/// This is used to detect other allocas which should be iterated on when
|
||||
/// doing direct promotion.
|
||||
ArrayRef<Value *> getStoredValues() const { return StoredValues; }
|
||||
|
||||
/// \brief Test whether a pointer to the allocation escapes our analysis.
|
||||
///
|
||||
/// If this is true, the slices are never fully built and should be
|
||||
@ -265,20 +253,10 @@ private:
|
||||
class SliceBuilder;
|
||||
friend class AllocaSlices::SliceBuilder;
|
||||
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||
/// \brief Handle to alloca instruction to simplify method interfaces.
|
||||
AllocaInst &AI;
|
||||
|
||||
/// \brief A flag indicating if the alloca is trivially promotable.
|
||||
///
|
||||
/// While walking the alloca's uses we track when the uses exceed what
|
||||
/// mem2reg can trivially handle. This essentially should match the logic in
|
||||
/// \c isAllocaPromotable but re-using the existing walk of the pointer uses.
|
||||
bool IsAllocaPromotable;
|
||||
|
||||
/// \brief Storage for stored values.
|
||||
///
|
||||
/// Only used while the alloca is trivially promotable.
|
||||
SmallVector<Value *, 8> StoredValues;
|
||||
#endif
|
||||
|
||||
/// \brief The instruction responsible for this alloca not having a known set
|
||||
/// of slices.
|
||||
@ -347,9 +325,9 @@ class AllocaSlices::SliceBuilder : public PtrUseVisitor<SliceBuilder> {
|
||||
SmallPtrSet<Instruction *, 4> VisitedDeadInsts;
|
||||
|
||||
public:
|
||||
SliceBuilder(const DataLayout &DL, AllocaSlices &S)
|
||||
SliceBuilder(const DataLayout &DL, AllocaInst &AI, AllocaSlices &S)
|
||||
: PtrUseVisitor<SliceBuilder>(DL),
|
||||
AllocSize(DL.getTypeAllocSize(S.AI.getAllocatedType())), S(S) {}
|
||||
AllocSize(DL.getTypeAllocSize(AI.getAllocatedType())), S(S) {}
|
||||
|
||||
private:
|
||||
void markAsDead(Instruction &I) {
|
||||
@ -402,15 +380,6 @@ private:
|
||||
if (GEPI.use_empty())
|
||||
return markAsDead(GEPI);
|
||||
|
||||
// FIXME: mem2reg shouldn't care about the nature of the GEP, but instead
|
||||
// the offsets of the loads. Until then, we short-circuit here for the
|
||||
// promotable case.
|
||||
if (GEPI.hasAllZeroIndices())
|
||||
return Base::enqueueUsers(GEPI);
|
||||
|
||||
// Otherwise, there is something in the GEP, so we disable mem2reg and
|
||||
// accumulate it.
|
||||
S.IsAllocaPromotable = false;
|
||||
return Base::visitGetElementPtrInst(GEPI);
|
||||
}
|
||||
|
||||
@ -427,13 +396,6 @@ private:
|
||||
bool IsSplittable =
|
||||
Ty->isIntegerTy() && !IsVolatile && Offset == 0 && Size >= AllocSize;
|
||||
|
||||
// mem2reg can only promote non-volatile loads and stores which exactly
|
||||
// load the alloca (no offset and the right type).
|
||||
if (IsVolatile || Offset != 0 || Ty != S.AI.getAllocatedType())
|
||||
S.IsAllocaPromotable = false;
|
||||
if (S.IsAllocaPromotable)
|
||||
assert(Offset == 0);
|
||||
|
||||
insertUse(I, Offset, Size, IsSplittable);
|
||||
}
|
||||
|
||||
@ -474,9 +436,6 @@ private:
|
||||
return markAsDead(SI);
|
||||
}
|
||||
|
||||
if (S.IsAllocaPromotable)
|
||||
S.StoredValues.push_back(ValOp);
|
||||
|
||||
assert((!SI.isSimple() || ValOp->getType()->isSingleValueType()) &&
|
||||
"All simple FCA stores should have been pre-split");
|
||||
handleLoadOrStore(ValOp->getType(), SI, Offset, Size, SI.isVolatile());
|
||||
@ -494,8 +453,6 @@ private:
|
||||
if (!IsOffsetKnown)
|
||||
return PI.setAborted(&II);
|
||||
|
||||
S.IsAllocaPromotable = false;
|
||||
|
||||
insertUse(II, Offset,
|
||||
Length ? Length->getLimitedValue()
|
||||
: AllocSize - Offset.getLimitedValue(),
|
||||
@ -512,8 +469,6 @@ private:
|
||||
if (!IsOffsetKnown)
|
||||
return PI.setAborted(&II);
|
||||
|
||||
S.IsAllocaPromotable = false;
|
||||
|
||||
uint64_t RawOffset = Offset.getLimitedValue();
|
||||
uint64_t Size = Length ? Length->getLimitedValue()
|
||||
: AllocSize - RawOffset;
|
||||
@ -574,8 +529,6 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
S.IsAllocaPromotable = false;
|
||||
|
||||
Base::visitIntrinsicInst(II);
|
||||
}
|
||||
|
||||
@ -650,8 +603,6 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
S.IsAllocaPromotable = false;
|
||||
|
||||
insertUse(PN, Offset, PHISize);
|
||||
}
|
||||
|
||||
@ -659,18 +610,14 @@ private:
|
||||
if (SI.use_empty())
|
||||
return markAsDead(SI);
|
||||
if (Value *Result = foldSelectInst(SI)) {
|
||||
if (Result == *U) {
|
||||
if (Result == *U)
|
||||
// If the result of the constant fold will be the pointer, recurse
|
||||
// through the select as if we had RAUW'ed it.
|
||||
enqueueUsers(SI);
|
||||
|
||||
// FIXME: mem2reg should support this pattern, but it doesn't.
|
||||
S.IsAllocaPromotable = false;
|
||||
} else {
|
||||
else
|
||||
// Otherwise the operand to the select is dead, and we can replace it
|
||||
// with undef.
|
||||
S.DeadOperands.push_back(U);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -697,8 +644,6 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
S.IsAllocaPromotable = false;
|
||||
|
||||
insertUse(SI, Offset, SelectSize);
|
||||
}
|
||||
|
||||
@ -709,8 +654,12 @@ private:
|
||||
};
|
||||
|
||||
AllocaSlices::AllocaSlices(const DataLayout &DL, AllocaInst &AI)
|
||||
: AI(AI), IsAllocaPromotable(true), PointerEscapingInstr(0) {
|
||||
SliceBuilder PB(DL, *this);
|
||||
:
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||
AI(AI),
|
||||
#endif
|
||||
PointerEscapingInstr(0) {
|
||||
SliceBuilder PB(DL, AI, *this);
|
||||
SliceBuilder::PtrInfo PtrI = PB.visitPtr(AI);
|
||||
if (PtrI.isEscaped() || PtrI.isAborted()) {
|
||||
// FIXME: We should sink the escape vs. abort info into the caller nicely,
|
||||
@ -3366,24 +3315,6 @@ bool SROA::runOnAlloca(AllocaInst &AI) {
|
||||
if (S.begin() == S.end())
|
||||
return Changed;
|
||||
|
||||
// Trivially promotable, don't go through the splitting and rewriting.
|
||||
if (S.isAllocaPromotable()) {
|
||||
DEBUG(dbgs() << " Directly promoting alloca: " << AI << "\n");
|
||||
PromotableAllocas.push_back(&AI);
|
||||
|
||||
// Walk through the stored values quickly here to handle directly
|
||||
// promotable allocas that require iterating on other allocas.
|
||||
ArrayRef<Value *> StoredValues = S.getStoredValues();
|
||||
for (ArrayRef<Value *>::iterator SVI = StoredValues.begin(),
|
||||
SVE = StoredValues.end();
|
||||
SVI != SVE; ++SVI)
|
||||
if ((*SVI)->getType()->isPointerTy())
|
||||
if (AllocaInst *SAI =
|
||||
dyn_cast<AllocaInst>((*SVI)->stripInBoundsOffsets()))
|
||||
PostPromotionWorklist.insert(SAI);
|
||||
return true;
|
||||
}
|
||||
|
||||
Changed |= splitAlloca(AI, S);
|
||||
|
||||
DEBUG(dbgs() << " Speculating PHIs\n");
|
||||
|
Loading…
Reference in New Issue
Block a user