1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-21 18:22:53 +01:00

[VPlan] Add mayReadOrWriteMemory & friends.

This patch adds initial implementation of mayReadOrWriteMemory,
mayReadFromMemory and mayWriteToMemory to VPRecipeBase.

Used by D100258.
This commit is contained in:
Florian Hahn 2021-05-14 23:18:04 +01:00
parent 55f27a8faa
commit db4bd974f6
3 changed files with 117 additions and 4 deletions

View File

@ -503,10 +503,75 @@ void VPRegionBlock::print(raw_ostream &O, const Twine &Indent,
}
#endif
bool VPRecipeBase::mayWriteToMemory() const {
switch (getVPDefID()) {
case VPWidenMemoryInstructionSC: {
return cast<VPWidenMemoryInstructionRecipe>(this)->isStore();
}
case VPReplicateSC:
case VPWidenCallSC:
return cast<Instruction>(getVPValue()->getUnderlyingValue())
->mayWriteToMemory();
case VPBranchOnMaskSC:
return false;
case VPWidenIntOrFpInductionSC:
case VPWidenCanonicalIVSC:
case VPWidenPHISC:
case VPBlendSC:
case VPWidenSC:
case VPWidenGEPSC:
case VPReductionSC:
case VPWidenSelectSC: {
const Instruction *I =
dyn_cast_or_null<Instruction>(getVPValue()->getUnderlyingValue());
(void)I;
assert((!I || !I->mayWriteToMemory()) &&
"underlying instruction may write to memory");
return false;
}
default:
return true;
}
}
bool VPRecipeBase::mayReadFromMemory() const {
switch (getVPDefID()) {
case VPWidenMemoryInstructionSC: {
return !cast<VPWidenMemoryInstructionRecipe>(this)->isStore();
}
case VPReplicateSC:
case VPWidenCallSC:
return cast<Instruction>(getVPValue()->getUnderlyingValue())
->mayReadFromMemory();
case VPBranchOnMaskSC:
return false;
case VPWidenIntOrFpInductionSC:
case VPWidenCanonicalIVSC:
case VPWidenPHISC:
case VPBlendSC:
case VPWidenSC:
case VPWidenGEPSC:
case VPReductionSC:
case VPWidenSelectSC: {
const Instruction *I =
dyn_cast_or_null<Instruction>(getVPValue()->getUnderlyingValue());
(void)I;
assert((!I || !I->mayReadFromMemory()) &&
"underlying instruction may read from memory");
return false;
}
default:
return true;
}
}
bool VPRecipeBase::mayHaveSideEffects() const {
switch (getVPDefID()) {
case VPBranchOnMaskSC:
return false;
case VPWidenIntOrFpInductionSC:
case VPWidenCanonicalIVSC:
case VPWidenPHISC:
case VPBlendSC:
case VPWidenSC:
case VPWidenGEPSC:

View File

@ -729,6 +729,17 @@ public:
return getVPDefID() == VPWidenIntOrFpInductionSC || getVPDefID() == VPWidenPHISC ||
getVPDefID() == VPPredInstPHISC || getVPDefID() == VPWidenCanonicalIVSC;
}
/// Returns true if the recipe may read from memory.
bool mayReadFromMemory() const;
/// Returns true if the recipe may write to memory.
bool mayWriteToMemory() const;
/// Returns true if the recipe may read from or write to memory.
bool mayReadOrWriteMemory() const {
return mayReadFromMemory() || mayWriteToMemory();
}
};
inline bool VPUser::classof(const VPDef *Def) {

View File

@ -949,7 +949,7 @@ TEST(VPRecipeTest, CastVPWidenMemoryInstructionRecipeToVPUserAndVPDef) {
delete Load;
}
TEST(VPRecipeTest, MayHaveSideEffects) {
TEST(VPRecipeTest, MayHaveSideEffectsAndMayReadWriteMemory) {
LLVMContext C;
IntegerType *Int1 = IntegerType::get(C, 1);
IntegerType *Int32 = IntegerType::get(C, 32);
@ -965,7 +965,9 @@ TEST(VPRecipeTest, MayHaveSideEffects) {
Args.push_back(&Op1);
VPWidenRecipe Recipe(*AI, make_range(Args.begin(), Args.end()));
EXPECT_FALSE(Recipe.mayHaveSideEffects());
EXPECT_FALSE(Recipe.mayReadFromMemory());
EXPECT_FALSE(Recipe.mayWriteToMemory());
EXPECT_FALSE(Recipe.mayReadOrWriteMemory());
delete AI;
}
@ -982,6 +984,9 @@ TEST(VPRecipeTest, MayHaveSideEffects) {
VPWidenSelectRecipe Recipe(*SelectI, make_range(Args.begin(), Args.end()),
false);
EXPECT_FALSE(Recipe.mayHaveSideEffects());
EXPECT_FALSE(Recipe.mayReadFromMemory());
EXPECT_FALSE(Recipe.mayWriteToMemory());
EXPECT_FALSE(Recipe.mayReadOrWriteMemory());
delete SelectI;
}
@ -995,6 +1000,9 @@ TEST(VPRecipeTest, MayHaveSideEffects) {
Args.push_back(&Op2);
VPWidenGEPRecipe Recipe(GEP, make_range(Args.begin(), Args.end()));
EXPECT_FALSE(Recipe.mayHaveSideEffects());
EXPECT_FALSE(Recipe.mayReadFromMemory());
EXPECT_FALSE(Recipe.mayWriteToMemory());
EXPECT_FALSE(Recipe.mayReadOrWriteMemory());
delete GEP;
}
@ -1002,6 +1010,9 @@ TEST(VPRecipeTest, MayHaveSideEffects) {
VPValue Mask;
VPBranchOnMaskRecipe Recipe(&Mask);
EXPECT_FALSE(Recipe.mayHaveSideEffects());
EXPECT_FALSE(Recipe.mayReadFromMemory());
EXPECT_FALSE(Recipe.mayWriteToMemory());
EXPECT_FALSE(Recipe.mayReadOrWriteMemory());
}
{
@ -1011,6 +1022,9 @@ TEST(VPRecipeTest, MayHaveSideEffects) {
VPReductionRecipe Recipe(nullptr, nullptr, &ChainOp, &CondOp, &VecOp,
nullptr);
EXPECT_FALSE(Recipe.mayHaveSideEffects());
EXPECT_FALSE(Recipe.mayReadFromMemory());
EXPECT_FALSE(Recipe.mayWriteToMemory());
EXPECT_FALSE(Recipe.mayReadOrWriteMemory());
}
{
@ -1020,10 +1034,26 @@ TEST(VPRecipeTest, MayHaveSideEffects) {
VPValue Mask;
VPWidenMemoryInstructionRecipe Recipe(*Load, &Addr, &Mask);
EXPECT_TRUE(Recipe.mayHaveSideEffects());
EXPECT_TRUE(Recipe.mayReadFromMemory());
EXPECT_FALSE(Recipe.mayWriteToMemory());
EXPECT_TRUE(Recipe.mayReadOrWriteMemory());
delete Load;
}
{
auto *Store = new StoreInst(UndefValue::get(Int32),
UndefValue::get(Int32Ptr), false, Align(1));
VPValue Addr;
VPValue Mask;
VPValue StoredV;
VPWidenMemoryInstructionRecipe Recipe(*Store, &Addr, &StoredV, &Mask);
EXPECT_TRUE(Recipe.mayHaveSideEffects());
EXPECT_FALSE(Recipe.mayReadFromMemory());
EXPECT_TRUE(Recipe.mayWriteToMemory());
EXPECT_TRUE(Recipe.mayReadOrWriteMemory());
delete Store;
}
{
FunctionType *FTy = FunctionType::get(Int32, false);
auto *Call = CallInst::Create(FTy, UndefValue::get(FTy));
@ -1034,6 +1064,9 @@ TEST(VPRecipeTest, MayHaveSideEffects) {
Args.push_back(&Op2);
VPWidenCallRecipe Recipe(*Call, make_range(Args.begin(), Args.end()));
EXPECT_TRUE(Recipe.mayHaveSideEffects());
EXPECT_TRUE(Recipe.mayReadFromMemory());
EXPECT_TRUE(Recipe.mayWriteToMemory());
EXPECT_TRUE(Recipe.mayReadOrWriteMemory());
delete Call;
}
@ -1041,8 +1074,12 @@ TEST(VPRecipeTest, MayHaveSideEffects) {
{
VPValue Op1;
VPValue Op2;
VPInstruction Recipe(Instruction::Add, {&Op1, &Op2});
VPInstruction VPInst(Instruction::Add, {&Op1, &Op2});
VPRecipeBase &Recipe = VPInst;
EXPECT_TRUE(Recipe.mayHaveSideEffects());
EXPECT_TRUE(Recipe.mayReadFromMemory());
EXPECT_TRUE(Recipe.mayWriteToMemory());
EXPECT_TRUE(Recipe.mayReadOrWriteMemory());
}
}