forked from OSchip/llvm-project
[PredicateInfo] Use SmallVector instead of SmallPtrSet.
We do not need the SmallPtrSet to avoid adding duplicates to OpsToRename, because we already keep a ValueInfo mapping. If we see an op for the first time, Infos will be empty and we can also add it to OpsToRename. We process operands by visiting BBs depth-first and then iterate over all instructions & users, so the order should be deterministic. Therefore we can skip one round of sorting, which we purely needed for guaranteeing a deterministic order when iterating over the SmallPtrSet. Reviewers: efriedma, davide Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D64816 llvm-svn: 367028
This commit is contained in:
parent
46441fdb3c
commit
c0d0e3bda8
|
@ -229,10 +229,10 @@ protected:
|
|||
|
||||
private:
|
||||
void buildPredicateInfo();
|
||||
void processAssume(IntrinsicInst *, BasicBlock *, SmallPtrSetImpl<Value *> &);
|
||||
void processBranch(BranchInst *, BasicBlock *, SmallPtrSetImpl<Value *> &);
|
||||
void processSwitch(SwitchInst *, BasicBlock *, SmallPtrSetImpl<Value *> &);
|
||||
void renameUses(SmallPtrSetImpl<Value *> &);
|
||||
void processAssume(IntrinsicInst *, BasicBlock *, SmallVectorImpl<Value *> &);
|
||||
void processBranch(BranchInst *, BasicBlock *, SmallVectorImpl<Value *> &);
|
||||
void processSwitch(SwitchInst *, BasicBlock *, SmallVectorImpl<Value *> &);
|
||||
void renameUses(SmallVectorImpl<Value *> &);
|
||||
using ValueDFS = PredicateInfoClasses::ValueDFS;
|
||||
typedef SmallVectorImpl<ValueDFS> ValueDFSStack;
|
||||
void convertUsesToDFSOrdered(Value *, SmallVectorImpl<ValueDFS> &);
|
||||
|
@ -240,7 +240,7 @@ private:
|
|||
bool stackIsInScope(const ValueDFSStack &, const ValueDFS &) const;
|
||||
void popStackUntilDFSScope(ValueDFSStack &, const ValueDFS &);
|
||||
ValueInfo &getOrCreateValueInfo(Value *);
|
||||
void addInfoFor(SmallPtrSetImpl<Value *> &OpsToRename, Value *Op,
|
||||
void addInfoFor(SmallVectorImpl<Value *> &OpsToRename, Value *Op,
|
||||
PredicateBase *PB);
|
||||
const ValueInfo &getValueInfo(Value *) const;
|
||||
Function &F;
|
||||
|
|
|
@ -306,10 +306,11 @@ void collectCmpOps(CmpInst *Comparison, SmallVectorImpl<Value *> &CmpOperands) {
|
|||
}
|
||||
|
||||
// Add Op, PB to the list of value infos for Op, and mark Op to be renamed.
|
||||
void PredicateInfo::addInfoFor(SmallPtrSetImpl<Value *> &OpsToRename, Value *Op,
|
||||
void PredicateInfo::addInfoFor(SmallVectorImpl<Value *> &OpsToRename, Value *Op,
|
||||
PredicateBase *PB) {
|
||||
OpsToRename.insert(Op);
|
||||
auto &OperandInfo = getOrCreateValueInfo(Op);
|
||||
if (OperandInfo.Infos.empty())
|
||||
OpsToRename.push_back(Op);
|
||||
AllInfos.push_back(PB);
|
||||
OperandInfo.Infos.push_back(PB);
|
||||
}
|
||||
|
@ -317,7 +318,7 @@ void PredicateInfo::addInfoFor(SmallPtrSetImpl<Value *> &OpsToRename, Value *Op,
|
|||
// Process an assume instruction and place relevant operations we want to rename
|
||||
// into OpsToRename.
|
||||
void PredicateInfo::processAssume(IntrinsicInst *II, BasicBlock *AssumeBB,
|
||||
SmallPtrSetImpl<Value *> &OpsToRename) {
|
||||
SmallVectorImpl<Value *> &OpsToRename) {
|
||||
// See if we have a comparison we support
|
||||
SmallVector<Value *, 8> CmpOperands;
|
||||
SmallVector<Value *, 2> ConditionsToProcess;
|
||||
|
@ -357,7 +358,7 @@ void PredicateInfo::processAssume(IntrinsicInst *II, BasicBlock *AssumeBB,
|
|||
// Process a block terminating branch, and place relevant operations to be
|
||||
// renamed into OpsToRename.
|
||||
void PredicateInfo::processBranch(BranchInst *BI, BasicBlock *BranchBB,
|
||||
SmallPtrSetImpl<Value *> &OpsToRename) {
|
||||
SmallVectorImpl<Value *> &OpsToRename) {
|
||||
BasicBlock *FirstBB = BI->getSuccessor(0);
|
||||
BasicBlock *SecondBB = BI->getSuccessor(1);
|
||||
SmallVector<BasicBlock *, 2> SuccsToProcess;
|
||||
|
@ -427,7 +428,7 @@ void PredicateInfo::processBranch(BranchInst *BI, BasicBlock *BranchBB,
|
|||
// Process a block terminating switch, and place relevant operations to be
|
||||
// renamed into OpsToRename.
|
||||
void PredicateInfo::processSwitch(SwitchInst *SI, BasicBlock *BranchBB,
|
||||
SmallPtrSetImpl<Value *> &OpsToRename) {
|
||||
SmallVectorImpl<Value *> &OpsToRename) {
|
||||
Value *Op = SI->getCondition();
|
||||
if ((!isa<Instruction>(Op) && !isa<Argument>(Op)) || Op->hasOneUse())
|
||||
return;
|
||||
|
@ -457,7 +458,7 @@ void PredicateInfo::buildPredicateInfo() {
|
|||
DT.updateDFSNumbers();
|
||||
// Collect operands to rename from all conditional branch terminators, as well
|
||||
// as assume statements.
|
||||
SmallPtrSet<Value *, 8> OpsToRename;
|
||||
SmallVector<Value *, 8> OpsToRename;
|
||||
for (auto DTN : depth_first(DT.getRootNode())) {
|
||||
BasicBlock *BranchBB = DTN->getBlock();
|
||||
if (auto *BI = dyn_cast<BranchInst>(BranchBB->getTerminator())) {
|
||||
|
@ -565,13 +566,7 @@ Value *PredicateInfo::materializeStack(unsigned int &Counter,
|
|||
//
|
||||
// TODO: Use this algorithm to perform fast single-variable renaming in
|
||||
// promotememtoreg and memoryssa.
|
||||
void PredicateInfo::renameUses(SmallPtrSetImpl<Value *> &OpSet) {
|
||||
// Sort OpsToRename since we are going to iterate it.
|
||||
SmallVector<Value *, 8> OpsToRename(OpSet.begin(), OpSet.end());
|
||||
auto Comparator = [&](const Value *A, const Value *B) {
|
||||
return valueComesBefore(OI, A, B);
|
||||
};
|
||||
llvm::sort(OpsToRename, Comparator);
|
||||
void PredicateInfo::renameUses(SmallVectorImpl<Value *> &OpsToRename) {
|
||||
ValueDFS_Compare Compare(OI);
|
||||
// Compute liveness, and rename in O(uses) per Op.
|
||||
for (auto *Op : OpsToRename) {
|
||||
|
|
|
@ -98,10 +98,10 @@ define void @test3(i32 %x, i32 %y) {
|
|||
; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
|
||||
; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
|
||||
; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]]
|
||||
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
|
||||
; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
|
||||
; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]])
|
||||
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
|
||||
; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]])
|
||||
; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
|
||||
; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]])
|
||||
; CHECK-NEXT: br i1 [[Z]], label [[BOTH_ZERO:%.*]], label [[NOPE:%.*]]
|
||||
; CHECK: both_zero:
|
||||
|
@ -382,8 +382,8 @@ ret:
|
|||
define i32 @test10(i32 %j, i32 %i) {
|
||||
; CHECK-LABEL: @test10(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], [[J:%.*]]
|
||||
; CHECK: [[J_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[J]])
|
||||
; CHECK: [[I_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[I]])
|
||||
; CHECK: [[J_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[J]])
|
||||
; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[RET:%.*]]
|
||||
; CHECK: cond_true:
|
||||
; CHECK-NEXT: [[DIFF:%.*]] = sub i32 [[I_0]], [[J_0]]
|
||||
|
|
|
@ -10,10 +10,10 @@ define void @testor(i32 %x, i32 %y) {
|
|||
; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
|
||||
; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
|
||||
; CHECK-NEXT: [[Z:%.*]] = or i1 [[XZ]], [[YZ]]
|
||||
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
|
||||
; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
|
||||
; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]])
|
||||
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
|
||||
; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]])
|
||||
; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
|
||||
; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]])
|
||||
; CHECK-NEXT: br i1 [[Z]], label [[ONEOF:%.*]], label [[NEITHER:%.*]]
|
||||
; CHECK: oneof:
|
||||
|
@ -54,10 +54,10 @@ define void @testand(i32 %x, i32 %y) {
|
|||
; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
|
||||
; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
|
||||
; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]]
|
||||
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
|
||||
; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
|
||||
; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]])
|
||||
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
|
||||
; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]])
|
||||
; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
|
||||
; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]])
|
||||
; CHECK-NEXT: br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
|
||||
; CHECK: both:
|
||||
|
@ -98,9 +98,9 @@ define void @testandsame(i32 %x, i32 %y) {
|
|||
; CHECK-NEXT: [[XGT:%.*]] = icmp sgt i32 [[X:%.*]], 0
|
||||
; CHECK-NEXT: [[XLT:%.*]] = icmp slt i32 [[X]], 100
|
||||
; CHECK-NEXT: [[Z:%.*]] = and i1 [[XGT]], [[XLT]]
|
||||
; CHECK: [[XGT_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XGT]])
|
||||
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
|
||||
; CHECK: [[X_0_1:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X_0]])
|
||||
; CHECK: [[XGT_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XGT]])
|
||||
; CHECK: [[XLT_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XLT]])
|
||||
; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]])
|
||||
; CHECK-NEXT: br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
|
||||
|
@ -136,23 +136,23 @@ define void @testandassume(i32 %x, i32 %y) {
|
|||
; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
|
||||
; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
|
||||
; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]]
|
||||
; CHECK: [[TMP1:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
|
||||
; CHECK: [[TMP2:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
|
||||
; CHECK: [[TMP3:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]])
|
||||
; CHECK: [[TMP4:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]])
|
||||
; CHECK: [[TMP1:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]])
|
||||
; CHECK: [[TMP2:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
|
||||
; CHECK: [[TMP3:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]])
|
||||
; CHECK: [[TMP4:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
|
||||
; CHECK: [[TMP5:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]])
|
||||
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP5]])
|
||||
; CHECK: [[DOT0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[TMP1]])
|
||||
; CHECK: [[DOT0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP1]])
|
||||
; CHECK: [[DOT01:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[TMP2]])
|
||||
; CHECK: [[DOT02:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP3]])
|
||||
; CHECK: [[DOT03:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP4]])
|
||||
; CHECK: [[DOT03:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[TMP4]])
|
||||
; CHECK: [[DOT04:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP5]])
|
||||
; CHECK-NEXT: br i1 [[TMP5]], label [[BOTH:%.*]], label [[NOPE:%.*]]
|
||||
; CHECK: both:
|
||||
; CHECK-NEXT: call void @foo(i1 [[DOT0]])
|
||||
; CHECK-NEXT: call void @foo(i1 [[DOT02]])
|
||||
; CHECK-NEXT: call void @foo(i1 [[DOT03]])
|
||||
; CHECK-NEXT: call void @bar(i32 [[DOT0]])
|
||||
; CHECK-NEXT: call void @bar(i32 [[DOT01]])
|
||||
; CHECK-NEXT: call void @bar(i32 [[DOT03]])
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: nope:
|
||||
; CHECK-NEXT: call void @foo(i1 [[DOT04]])
|
||||
|
|
Loading…
Reference in New Issue