Commit 2e4b960b by Manasij Mukherjee

Catch addition patterns for Index in Address Optimization

Index is Index=Var+Const ==> set Index=Var, Offset+=(Const<<Shift) Index is Index=Const+Var ==> set Index=Var, Offset+=(Const<<Shift) Index is Index=Var-Const ==> set Index=Var, Offset-=(Const<<Shift) BUG=none R=stichnot@chromium.org Review URL: https://codereview.chromium.org/2084793002 .
parent 227c9f39
...@@ -5070,9 +5070,10 @@ public: ...@@ -5070,9 +5070,10 @@ public:
inline const Inst *matchShiftedIndex(Variable **Index, uint16_t *Shift); inline const Inst *matchShiftedIndex(Variable **Index, uint16_t *Shift);
inline const Inst *matchOffsetBase(Variable **Base, inline const Inst *matchOffsetIndexOrBase(Variable **IndexOrBase,
ConstantRelocatable **Relocatable, const uint16_t Shift,
int32_t *Offset); ConstantRelocatable **Relocatable,
int32_t *Offset);
private: private:
const Cfg *const Func; const Cfg *const Func;
...@@ -5256,22 +5257,29 @@ const Inst *AddressOptimizer::matchShiftedIndex(Variable **Index, ...@@ -5256,22 +5257,29 @@ const Inst *AddressOptimizer::matchShiftedIndex(Variable **Index,
return nullptr; return nullptr;
} }
const Inst *AddressOptimizer::matchOffsetBase(Variable **Base, const Inst *AddressOptimizer::matchOffsetIndexOrBase(
ConstantRelocatable **Relocatable, Variable **IndexOrBase, const uint16_t Shift,
int32_t *Offset) { ConstantRelocatable **Relocatable, int32_t *Offset) {
// Base is Base=Var+Const || Base is Base=Const+Var ==> // Base is Base=Var+Const || Base is Base=Const+Var ==>
// set Base=Var, Offset+=Const // set Base=Var, Offset+=Const
// Base is Base=Var-Const ==> // Base is Base=Var-Const ==>
// set Base=Var, Offset-=Const // set Base=Var, Offset-=Const
if (*Base == nullptr) { // Index is Index=Var+Const ==>
// set Index=Var, Offset+=(Const<<Shift)
// Index is Index=Const+Var ==>
// set Index=Var, Offset+=(Const<<Shift)
// Index is Index=Var-Const ==>
// set Index=Var, Offset-=(Const<<Shift)
if (*IndexOrBase == nullptr) {
return nullptr; return nullptr;
} }
const Inst *BaseInst = VMetadata->getSingleDefinition(*Base); const Inst *Definition = VMetadata->getSingleDefinition(*IndexOrBase);
if (BaseInst == nullptr) { if (Definition == nullptr) {
return nullptr; return nullptr;
} }
assert(!VMetadata->isMultiDef(*Base)); assert(!VMetadata->isMultiDef(*IndexOrBase));
if (auto *ArithInst = llvm::dyn_cast<const InstArithmetic>(BaseInst)) { if (auto *ArithInst = llvm::dyn_cast<const InstArithmetic>(Definition)) {
if (ArithInst->getOp() != InstArithmetic::Add && if (ArithInst->getOp() != InstArithmetic::Add &&
ArithInst->getOp() != InstArithmetic::Sub) ArithInst->getOp() != InstArithmetic::Sub)
return nullptr; return nullptr;
...@@ -5284,8 +5292,8 @@ const Inst *AddressOptimizer::matchOffsetBase(Variable **Base, ...@@ -5284,8 +5292,8 @@ const Inst *AddressOptimizer::matchOffsetBase(Variable **Base,
auto *Const1 = llvm::dyn_cast<ConstantInteger32>(Src1); auto *Const1 = llvm::dyn_cast<ConstantInteger32>(Src1);
auto *Reloc0 = llvm::dyn_cast<ConstantRelocatable>(Src0); auto *Reloc0 = llvm::dyn_cast<ConstantRelocatable>(Src0);
auto *Reloc1 = llvm::dyn_cast<ConstantRelocatable>(Src1); auto *Reloc1 = llvm::dyn_cast<ConstantRelocatable>(Src1);
Variable *NewBase = nullptr; Variable *NewIndexOrBase = nullptr;
int32_t NewOffset = *Offset; int32_t NewOffset = 0;
ConstantRelocatable *NewRelocatable = *Relocatable; ConstantRelocatable *NewRelocatable = *Relocatable;
if (Var0 && Var1) if (Var0 && Var1)
// TODO(sehr): merge base/index splitting into here. // TODO(sehr): merge base/index splitting into here.
...@@ -5293,9 +5301,9 @@ const Inst *AddressOptimizer::matchOffsetBase(Variable **Base, ...@@ -5293,9 +5301,9 @@ const Inst *AddressOptimizer::matchOffsetBase(Variable **Base,
if (!IsAdd && Var1) if (!IsAdd && Var1)
return nullptr; return nullptr;
if (Var0) if (Var0)
NewBase = Var0; NewIndexOrBase = Var0;
else if (Var1) else if (Var1)
NewBase = Var1; NewIndexOrBase = Var1;
// Don't know how to add/subtract two relocatables. // Don't know how to add/subtract two relocatables.
if ((*Relocatable && (Reloc0 || Reloc1)) || (Reloc0 && Reloc1)) if ((*Relocatable && (Reloc0 || Reloc1)) || (Reloc0 && Reloc1))
return nullptr; return nullptr;
...@@ -5311,21 +5319,24 @@ const Inst *AddressOptimizer::matchOffsetBase(Variable **Base, ...@@ -5311,21 +5319,24 @@ const Inst *AddressOptimizer::matchOffsetBase(Variable **Base,
if (Const0) { if (Const0) {
const int32_t MoreOffset = const int32_t MoreOffset =
IsAdd ? Const0->getValue() : -Const0->getValue(); IsAdd ? Const0->getValue() : -Const0->getValue();
if (Utils::WouldOverflowAdd(NewOffset, MoreOffset)) if (Utils::WouldOverflowAdd(*Offset + NewOffset, MoreOffset))
return nullptr; return nullptr;
NewOffset += MoreOffset; NewOffset += MoreOffset;
} }
if (Const1) { if (Const1) {
const int32_t MoreOffset = const int32_t MoreOffset =
IsAdd ? Const1->getValue() : -Const1->getValue(); IsAdd ? Const1->getValue() : -Const1->getValue();
if (Utils::WouldOverflowAdd(NewOffset, MoreOffset)) if (Utils::WouldOverflowAdd(*Offset + NewOffset, MoreOffset))
return nullptr; return nullptr;
NewOffset += MoreOffset; NewOffset += MoreOffset;
} }
*Base = NewBase; if (Utils::WouldOverflowAdd(*Offset, NewOffset << Shift))
*Offset = NewOffset; return nullptr;
*IndexOrBase = NewIndexOrBase;
*Offset += (NewOffset << Shift);
// Shift is always zero if this is called with the base
*Relocatable = NewRelocatable; *Relocatable = NewRelocatable;
return BaseInst; return Definition;
} }
return nullptr; return nullptr;
} }
...@@ -5460,26 +5471,19 @@ TargetX86Base<TypeTraits>::computeAddressOpt(const Inst *Instr, Type MemType, ...@@ -5460,26 +5471,19 @@ TargetX86Base<TypeTraits>::computeAddressOpt(const Inst *Instr, Type MemType,
// Update Offset to reflect additions/subtractions with constants and // Update Offset to reflect additions/subtractions with constants and
// relocatables. // relocatables.
// TODO: consider overflow issues with respect to Offset. // TODO: consider overflow issues with respect to Offset.
if (!Skip.OffsetFromBase && if (!Skip.OffsetFromBase && (Reason = AddrOpt.matchOffsetIndexOrBase(
(Reason = AddrOpt.matchOffsetBase(&NewAddr.Base, &NewAddr.Relocatable, &NewAddr.Base, /*Shift =*/0,
&NewAddr.Offset))) { &NewAddr.Relocatable, &NewAddr.Offset))) {
SkipLastFolding = &Skip.OffsetFromBase; SkipLastFolding = &Skip.OffsetFromBase;
continue; continue;
} }
if (NewAddr.Shift == 0 && !Skip.OffsetFromIndex && if (!Skip.OffsetFromIndex && (Reason = AddrOpt.matchOffsetIndexOrBase(
(Reason = AddrOpt.matchOffsetBase(&NewAddr.Index, &NewAddr.Relocatable, &NewAddr.Index, NewAddr.Shift,
&NewAddr.Offset))) { &NewAddr.Relocatable, &NewAddr.Offset))) {
SkipLastFolding = &Skip.OffsetFromIndex; SkipLastFolding = &Skip.OffsetFromIndex;
continue; continue;
} }
// TODO(sehr, stichnot): Handle updates of Index with Shift != 0.
// Index is Index=Var+Const ==>
// set Index=Var, Offset+=(Const<<Shift)
// Index is Index=Const+Var ==>
// set Index=Var, Offset+=(Const<<Shift)
// Index is Index=Var-Const ==>
// set Index=Var, Offset-=(Const<<Shift)
break; break;
} while (Reason); } while (Reason);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment