Skip to content
75 changes: 42 additions & 33 deletions llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,15 @@ struct PromoteMem2Reg {
/// number.
SmallVector<unsigned> BBNumPreds;

/// The state of incoming values for the current DFS step.
RenamePassData::ValVector IncomingVals;

/// The state of incoming locations for the current DFS step.
RenamePassData::LocationVector IncomingLocs;

// DFS work stack.
SmallVector<RenamePassData, 8> Worklist;

/// Whether the function has the no-signed-zeros-fp-math attribute set.
bool NoSignedZeros = false;

Expand Down Expand Up @@ -423,10 +432,7 @@ struct PromoteMem2Reg {
void ComputeLiveInBlocks(AllocaInst *AI, AllocaInfo &Info,
const SmallPtrSetImpl<BasicBlock *> &DefBlocks,
SmallPtrSetImpl<BasicBlock *> &LiveInBlocks);
void RenamePass(BasicBlock *BB, BasicBlock *Pred,
RenamePassData::ValVector &IncVals,
RenamePassData::LocationVector &IncLocs,
std::vector<RenamePassData> &Worklist);
void RenamePass(BasicBlock *BB, BasicBlock *Pred);
bool QueuePhiNode(BasicBlock *BB, unsigned AllocaIdx, unsigned &Version);

/// Delete dbg.assigns that have been demoted to dbg.values.
Expand All @@ -438,6 +444,20 @@ struct PromoteMem2Reg {
DVR->eraseFromParent();
DVRAssignsToDelete.clear();
}

void pushToWorklist(BasicBlock *BB, BasicBlock *Pred,
RenamePassData::ValVector IncVals,
RenamePassData::LocationVector IncLocs) {
Worklist.emplace_back(BB, Pred, std::move(IncVals), std::move(IncLocs));
}

RenamePassData popFromWorklist() {
RenamePassData R = std::move(Worklist.back());
Worklist.pop_back();
IncomingVals = std::move(R.Values);
IncomingLocs = std::move(R.Locations);
return R;
}
};

} // end anonymous namespace
Expand Down Expand Up @@ -849,28 +869,26 @@ void PromoteMem2Reg::run() {
// Set the incoming values for the basic block to be null values for all of
// the alloca's. We do this in case there is a load of a value that has not
// been stored yet. In this case, it will get this null value.
RenamePassData::ValVector Values(Allocas.size());
IncomingVals.assign(Allocas.size(), nullptr);
for (unsigned i = 0, e = Allocas.size(); i != e; ++i)
Values[i] = UndefValue::get(Allocas[i]->getAllocatedType());
IncomingVals[i] = UndefValue::get(Allocas[i]->getAllocatedType());

// When handling debug info, treat all incoming values as if they have unknown
// locations until proven otherwise.
RenamePassData::LocationVector Locations(Allocas.size());
IncomingLocs.assign(Allocas.size(), {});

// The renamer uses the Visited set to avoid infinite loops.
Visited.resize(F.getMaxBlockNumber());

// Walks all basic blocks in the function performing the SSA rename algorithm
// and inserting the phi nodes we marked as necessary
std::vector<RenamePassData> RenamePassWorkList;
RenamePassWorkList.emplace_back(&F.front(), nullptr, std::move(Values),
std::move(Locations));
pushToWorklist(&F.front(), nullptr, std::move(IncomingVals),
std::move(IncomingLocs));
do {
RenamePassData RPD = std::move(RenamePassWorkList.back());
RenamePassWorkList.pop_back();
RenamePassData RPD = popFromWorklist();
// RenamePass may add new worklist entries.
RenamePass(RPD.BB, RPD.Pred, RPD.Values, RPD.Locations, RenamePassWorkList);
} while (!RenamePassWorkList.empty());
RenamePass(RPD.BB, RPD.Pred);
} while (!Worklist.empty());

// Remove the allocas themselves from the function.
for (Instruction *A : Allocas) {
Expand Down Expand Up @@ -1095,11 +1113,7 @@ static void updateForIncomingValueLocation(PHINode *PN, DebugLoc DL,
///
/// IncomingVals indicates what value each Alloca contains on exit from the
/// predecessor block Pred.
void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred,
RenamePassData::ValVector &IncomingVals,
RenamePassData::LocationVector &IncomingLocs,
std::vector<RenamePassData> &Worklist) {
NextIteration:
void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred) {
// If we are inserting any phi nodes into this BB, they will already be in the
// block.
if (PHINode *APN = dyn_cast<PHINode>(BB->begin())) {
Expand Down Expand Up @@ -1215,24 +1229,19 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred,
}

// 'Recurse' to our successors.
succ_iterator I = succ_begin(BB), E = succ_end(BB);
if (I == E)
return;

// Keep track of the successors so we don't visit the same successor twice
SmallPtrSet<BasicBlock *, 8> VisitedSuccs;

// Handle the first successor without using the worklist.
VisitedSuccs.insert(*I);
Pred = BB;
BB = *I;
++I;

for (; I != E; ++I)
if (VisitedSuccs.insert(*I).second)
Worklist.emplace_back(*I, Pred, IncomingVals, IncomingLocs);

goto NextIteration;
for (BasicBlock *S : reverse(successors(BB)))
if (VisitedSuccs.insert(S).second) {
if (VisitedSuccs.size() > 1) {
// Let the first successor own allocated arrays, other will make a copy.
IncomingVals = Worklist.back().Values;
IncomingLocs = Worklist.back().Locations;
}
pushToWorklist(S, BB, std::move(IncomingVals), std::move(IncomingLocs));
}
}

void llvm::PromoteMemToReg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ define ptr @_Z3fooRSt6vectorIiSaIiEE(ptr %X) {
; IC_SROA-NEXT: [[TMP27:%.*]] = getelementptr i8, ptr [[__FIRST_ADDR_I_I_SROA_0_0]], i32 4
; IC_SROA-NEXT: br label [[BB18_I_I]]
; IC_SROA: bb18.i.i:
; IC_SROA-NEXT: [[__FIRST_ADDR_I_I_SROA_0_1:%.*]] = phi ptr [ [[TMP27]], [[BB17_I_I]] ], [ [[__FIRST_ADDR_I_I_SROA_0_0]], [[BB13_I_I]] ]
; IC_SROA-NEXT: [[__FIRST_ADDR_I_I_SROA_0_1:%.*]] = phi ptr [ [[__FIRST_ADDR_I_I_SROA_0_0]], [[BB13_I_I]] ], [ [[TMP27]], [[BB17_I_I]] ]
; IC_SROA-NEXT: [[TMP28:%.*]] = load i32, ptr [[__FIRST_ADDR_I_I_SROA_0_1]], align 4
; IC_SROA-NEXT: [[TMP29:%.*]] = icmp eq i32 [[TMP28]], 42
; IC_SROA-NEXT: br i1 [[TMP29]], label [[BB20_I_I:%.*]], label [[BB21_I_I:%.*]]
Expand All @@ -225,7 +225,7 @@ define ptr @_Z3fooRSt6vectorIiSaIiEE(ptr %X) {
; IC_SROA-NEXT: [[TMP30:%.*]] = getelementptr i8, ptr [[__FIRST_ADDR_I_I_SROA_0_1]], i32 4
; IC_SROA-NEXT: br label [[BB22_I_I]]
; IC_SROA: bb22.i.i:
; IC_SROA-NEXT: [[__FIRST_ADDR_I_I_SROA_0_2:%.*]] = phi ptr [ [[TMP30]], [[BB21_I_I]] ], [ [[__FIRST_ADDR_I_I_SROA_0_0]], [[BB13_I_I]] ]
; IC_SROA-NEXT: [[__FIRST_ADDR_I_I_SROA_0_2:%.*]] = phi ptr [ [[__FIRST_ADDR_I_I_SROA_0_0]], [[BB13_I_I]] ], [ [[TMP30]], [[BB21_I_I]] ]
; IC_SROA-NEXT: [[TMP31:%.*]] = load i32, ptr [[__FIRST_ADDR_I_I_SROA_0_2]], align 4
; IC_SROA-NEXT: [[TMP32:%.*]] = icmp eq i32 [[TMP31]], 42
; IC_SROA-NEXT: br i1 [[TMP32]], label [[BB24_I_I:%.*]], label [[BB25_I_I:%.*]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ define i32 @foo(i32 %x) #0 section ".tcm_text" {
; DISABLE: sw.default:
; DISABLE-NEXT: br label [[RETURN]]
; DISABLE: return:
; DISABLE-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 19, [[SW_DEFAULT]] ], [ 33, [[SW_BB5]] ], [ 12, [[SW_BB4]] ], [ 22, [[SW_BB3]] ], [ 14, [[SW_BB2]] ], [ 20, [[SW_BB1]] ], [ 9, [[ENTRY:%.*]] ]
; DISABLE-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 19, [[SW_DEFAULT]] ], [ 20, [[SW_BB1]] ], [ 14, [[SW_BB2]] ], [ 22, [[SW_BB3]] ], [ 12, [[SW_BB4]] ], [ 33, [[SW_BB5]] ], [ 9, [[ENTRY:%.*]] ]
; DISABLE-NEXT: ret i32 [[RETVAL_0]]
;
entry:
Expand Down
Loading