mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
[SCEV] Generalize SCEVParameterRewriter to accept SCEV expression as target.
This patch extends SCEVParameterRewriter to support rewriting unknown epxressions to arbitrary SCEV expressions. It will be used by further patches. Reviewed By: reames Differential Revision: https://reviews.llvm.org/D67176
This commit is contained in:
parent
7fb62030d9
commit
447cd8eb56
@ -810,35 +810,30 @@ class Type;
|
|||||||
};
|
};
|
||||||
|
|
||||||
using ValueToValueMap = DenseMap<const Value *, Value *>;
|
using ValueToValueMap = DenseMap<const Value *, Value *>;
|
||||||
|
using ValueToSCEVMapTy = DenseMap<const Value *, const SCEV *>;
|
||||||
|
|
||||||
/// The SCEVParameterRewriter takes a scalar evolution expression and updates
|
/// The SCEVParameterRewriter takes a scalar evolution expression and updates
|
||||||
/// the SCEVUnknown components following the Map (Value -> Value).
|
/// the SCEVUnknown components following the Map (Value -> SCEV).
|
||||||
class SCEVParameterRewriter : public SCEVRewriteVisitor<SCEVParameterRewriter> {
|
class SCEVParameterRewriter : public SCEVRewriteVisitor<SCEVParameterRewriter> {
|
||||||
public:
|
public:
|
||||||
static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE,
|
static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE,
|
||||||
ValueToValueMap &Map,
|
ValueToSCEVMapTy &Map) {
|
||||||
bool InterpretConsts = false) {
|
SCEVParameterRewriter Rewriter(SE, Map);
|
||||||
SCEVParameterRewriter Rewriter(SE, Map, InterpretConsts);
|
|
||||||
return Rewriter.visit(Scev);
|
return Rewriter.visit(Scev);
|
||||||
}
|
}
|
||||||
|
|
||||||
SCEVParameterRewriter(ScalarEvolution &SE, ValueToValueMap &M, bool C)
|
SCEVParameterRewriter(ScalarEvolution &SE, ValueToSCEVMapTy &M)
|
||||||
: SCEVRewriteVisitor(SE), Map(M), InterpretConsts(C) {}
|
: SCEVRewriteVisitor(SE), Map(M) {}
|
||||||
|
|
||||||
const SCEV *visitUnknown(const SCEVUnknown *Expr) {
|
const SCEV *visitUnknown(const SCEVUnknown *Expr) {
|
||||||
Value *V = Expr->getValue();
|
auto I = Map.find(Expr->getValue());
|
||||||
if (Map.count(V)) {
|
if (I == Map.end())
|
||||||
Value *NV = Map[V];
|
return Expr;
|
||||||
if (InterpretConsts && isa<ConstantInt>(NV))
|
return I->second;
|
||||||
return SE.getConstant(cast<ConstantInt>(NV));
|
|
||||||
return SE.getUnknown(NV);
|
|
||||||
}
|
|
||||||
return Expr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ValueToValueMap ⤅
|
ValueToSCEVMapTy ⤅
|
||||||
bool InterpretConsts;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using LoopToScevMapT = DenseMap<const Loop *, const SCEV *>;
|
using LoopToScevMapT = DenseMap<const Loop *, const SCEV *>;
|
||||||
|
@ -215,16 +215,14 @@ void SCEVDivision::visitMulExpr(const SCEVMulExpr *Numerator) {
|
|||||||
return cannotDivide(Numerator);
|
return cannotDivide(Numerator);
|
||||||
|
|
||||||
// The Remainder is obtained by replacing Denominator by 0 in Numerator.
|
// The Remainder is obtained by replacing Denominator by 0 in Numerator.
|
||||||
ValueToValueMap RewriteMap;
|
ValueToSCEVMapTy RewriteMap;
|
||||||
RewriteMap[cast<SCEVUnknown>(Denominator)->getValue()] =
|
RewriteMap[cast<SCEVUnknown>(Denominator)->getValue()] = Zero;
|
||||||
cast<SCEVConstant>(Zero)->getValue();
|
Remainder = SCEVParameterRewriter::rewrite(Numerator, SE, RewriteMap);
|
||||||
Remainder = SCEVParameterRewriter::rewrite(Numerator, SE, RewriteMap, true);
|
|
||||||
|
|
||||||
if (Remainder->isZero()) {
|
if (Remainder->isZero()) {
|
||||||
// The Quotient is obtained by replacing Denominator by 1 in Numerator.
|
// The Quotient is obtained by replacing Denominator by 1 in Numerator.
|
||||||
RewriteMap[cast<SCEVUnknown>(Denominator)->getValue()] =
|
RewriteMap[cast<SCEVUnknown>(Denominator)->getValue()] = One;
|
||||||
cast<SCEVConstant>(One)->getValue();
|
Quotient = SCEVParameterRewriter::rewrite(Numerator, SE, RewriteMap);
|
||||||
Quotient = SCEVParameterRewriter::rewrite(Numerator, SE, RewriteMap, true);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,6 +149,12 @@ static Instruction *getInstructionByName(Function &F, StringRef Name) {
|
|||||||
llvm_unreachable("Expected to find instruction!");
|
llvm_unreachable("Expected to find instruction!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Value *getArgByName(Function &F, StringRef Name) {
|
||||||
|
for (auto &Arg : F.args())
|
||||||
|
if (Arg.getName() == Name)
|
||||||
|
return &Arg;
|
||||||
|
llvm_unreachable("Expected to find instruction!");
|
||||||
|
}
|
||||||
TEST_F(ScalarEvolutionsTest, CommutativeExprOperandOrder) {
|
TEST_F(ScalarEvolutionsTest, CommutativeExprOperandOrder) {
|
||||||
LLVMContext C;
|
LLVMContext C;
|
||||||
SMDiagnostic Err;
|
SMDiagnostic Err;
|
||||||
@ -1120,4 +1126,43 @@ TEST_F(ScalarEvolutionsTest, SCEVComputeConstantDifference) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ScalarEvolutionsTest, SCEVrewriteUnknowns) {
|
||||||
|
LLVMContext C;
|
||||||
|
SMDiagnostic Err;
|
||||||
|
std::unique_ptr<Module> M = parseAssemblyString(
|
||||||
|
"define void @foo(i32 %i) { "
|
||||||
|
"entry: "
|
||||||
|
" %cmp3 = icmp ult i32 %i, 16 "
|
||||||
|
" br i1 %cmp3, label %loop.body, label %exit "
|
||||||
|
"loop.body: "
|
||||||
|
" %iv = phi i32 [ %iv.next, %loop.body ], [ %i, %entry ] "
|
||||||
|
" %iv.next = add nsw i32 %iv, 1 "
|
||||||
|
" %cmp = icmp eq i32 %iv.next, 16 "
|
||||||
|
" br i1 %cmp, label %exit, label %loop.body "
|
||||||
|
"exit: "
|
||||||
|
" ret void "
|
||||||
|
"} ",
|
||||||
|
Err, C);
|
||||||
|
|
||||||
|
ASSERT_TRUE(M && "Could not parse module?");
|
||||||
|
ASSERT_TRUE(!verifyModule(*M) && "Must have been well formed!");
|
||||||
|
|
||||||
|
runWithSE(*M, "foo", [](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
|
||||||
|
auto *ScevIV = SE.getSCEV(getInstructionByName(F, "iv")); // {0,+,1}
|
||||||
|
auto *ScevI = SE.getSCEV(getArgByName(F, "i")); // {0,+,1}
|
||||||
|
|
||||||
|
ValueToSCEVMapTy RewriteMap;
|
||||||
|
RewriteMap[cast<SCEVUnknown>(ScevI)->getValue()] =
|
||||||
|
SE.getUMinExpr(ScevI, SE.getConstant(ScevI->getType(), 17));
|
||||||
|
auto *WithUMin = SCEVParameterRewriter::rewrite(ScevIV, SE, RewriteMap);
|
||||||
|
|
||||||
|
EXPECT_NE(WithUMin, ScevIV);
|
||||||
|
auto *AR = dyn_cast<SCEVAddRecExpr>(WithUMin);
|
||||||
|
EXPECT_TRUE(AR);
|
||||||
|
EXPECT_EQ(AR->getStart(),
|
||||||
|
SE.getUMinExpr(ScevI, SE.getConstant(ScevI->getType(), 17)));
|
||||||
|
EXPECT_EQ(AR->getStepRecurrence(SE),
|
||||||
|
cast<SCEVAddRecExpr>(ScevIV)->getStepRecurrence(SE));
|
||||||
|
});
|
||||||
|
}
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
Loading…
Reference in New Issue
Block a user