Chromium Code Reviews| Index: src/IceTargetLoweringX86BaseImpl.h |
| diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h |
| index 49c929b8a5983393e4ddf02cc910c100cb5c6951..ec2487112d65f9f460e768be4fca53ae4f7d898b 100644 |
| --- a/src/IceTargetLoweringX86BaseImpl.h |
| +++ b/src/IceTargetLoweringX86BaseImpl.h |
| @@ -5270,6 +5270,9 @@ const Inst *AddressOptimizer::matchOffsetIndexOrBase( |
| // set Index=Var, Offset+=(Const<<Shift) |
| // Index is Index=Var-Const ==> |
| // set Index=Var, Offset-=(Const<<Shift) |
| + // Treat Index=Var Or Const as Index=Var + Const |
| + // when Var = Var' << N and log2(Const) <= N |
| + // or when Var = (2^M) * (2^N) and log2(Const) <= (M+N) |
| if (*IndexOrBase == nullptr) { |
| return nullptr; |
| @@ -5281,9 +5284,10 @@ const Inst *AddressOptimizer::matchOffsetIndexOrBase( |
| assert(!VMetadata->isMultiDef(*IndexOrBase)); |
| if (auto *ArithInst = llvm::dyn_cast<const InstArithmetic>(Definition)) { |
| if (ArithInst->getOp() != InstArithmetic::Add && |
| - ArithInst->getOp() != InstArithmetic::Sub) |
| + ArithInst->getOp() != InstArithmetic::Sub && |
| + ArithInst->getOp() != InstArithmetic::Or) |
|
Jim Stichnoth
2016/06/22 20:01:14
Once we're up to testing 3 values, I think this sh
manasijm
2016/06/27 18:04:18
Done.
|
| return nullptr; |
| - bool IsAdd = ArithInst->getOp() == InstArithmetic::Add; |
| + |
| Operand *Src0 = ArithInst->getSrc(0); |
| Operand *Src1 = ArithInst->getSrc(1); |
| auto *Var0 = llvm::dyn_cast<Variable>(Src0); |
| @@ -5292,6 +5296,57 @@ const Inst *AddressOptimizer::matchOffsetIndexOrBase( |
| auto *Const1 = llvm::dyn_cast<ConstantInteger32>(Src1); |
| auto *Reloc0 = llvm::dyn_cast<ConstantRelocatable>(Src0); |
| auto *Reloc1 = llvm::dyn_cast<ConstantRelocatable>(Src1); |
| + |
| + bool IsAdd = false; |
| + if (ArithInst->getOp() == InstArithmetic::Or) { |
| + Variable *Var = nullptr; |
| + ConstantInteger32 *Const = nullptr; |
| + if (Var0 && Const1) { |
| + Var = Var0; |
| + Const = Const1; |
| + } else if (Const0 && Var1) { |
| + Var = Var1; |
| + Const = Const0; |
| + } else |
| + return nullptr; |
| + |
| + auto *VarDef = |
| + llvm::dyn_cast<InstArithmetic>(VMetadata->getSingleDefinition(Var)); |
| + if (VarDef == nullptr) |
| + return nullptr; |
| + |
| + auto uintLog2 = [](uint32_t x) { |
|
Jim Stichnoth
2016/06/22 20:01:13
Can you just use llvm::Log2_32() or similar?
See
manasijm
2016/06/27 18:04:18
Done.
|
| + uint8_t result = 0; |
| + if (x > 0) do {result++;} while (x >>= 1); |
| + return result; |
| + }; |
| + |
| + SizeT numZeroes = 0; |
|
Jim Stichnoth
2016/06/22 20:01:13
NumZeroes
manasijm
2016/06/27 18:04:18
Done.
|
| + if (VarDef->getOp() == InstArithmetic::Shl) { |
| + if (auto ConstInt = |
|
Jim Stichnoth
2016/06/22 20:01:13
auto *
manasijm
2016/06/27 18:04:18
Done.
|
| + llvm::dyn_cast<ConstantInteger32>(VarDef->getSrc(1))) { |
| + numZeroes = ConstInt->getValue(); |
| + } |
| + } else if (VarDef->getOp() == InstArithmetic::Mul) { |
| + ConstantInteger32 *MultConst = nullptr; |
|
Jim Stichnoth
2016/06/22 20:01:13
Combine this and the next line.
manasijm
2016/06/27 18:04:18
Done.
|
| + MultConst = llvm::dyn_cast<ConstantInteger32>(VarDef->getSrc(0)); |
| + if (llvm::isPowerOf2_32(MultConst->getValue())) { |
| + numZeroes += uintLog2(MultConst->getValue()); |
| + } |
| + MultConst = llvm::dyn_cast<ConstantInteger32>(VarDef->getSrc(1)); |
| + if (llvm::isPowerOf2_32(MultConst->getValue())) { |
| + numZeroes += uintLog2(MultConst->getValue()); |
| + } |
| + } |
| + SizeT LogValue = uintLog2(Const->getValue()); |
| + if (LogValue == 0 || LogValue > numZeroes) |
| + return nullptr; |
| + |
| + IsAdd = true; // treat it as an add if the above conditions hold |
| + } else { |
| + IsAdd = ArithInst->getOp() == InstArithmetic::Add; |
| + } |
| + |
| Variable *NewIndexOrBase = nullptr; |
| int32_t NewOffset = 0; |
| ConstantRelocatable *NewRelocatable = *Relocatable; |
| @@ -5331,7 +5386,7 @@ const Inst *AddressOptimizer::matchOffsetIndexOrBase( |
| NewOffset += MoreOffset; |
| } |
| if (Utils::WouldOverflowAdd(*Offset, NewOffset << Shift)) |
| - return nullptr; |
| + return nullptr; |
| *IndexOrBase = NewIndexOrBase; |
| *Offset += (NewOffset << Shift); |
| // Shift is always zero if this is called with the base |