Commit 5b7e1c06 by Manasij Mukherjee

Aggressive LEA

Convert adds with a constant operand to lea on -aggressive-lea BUG=none R=stichnot@chromium.org Review URL: https://codereview.chromium.org/2135403002 .
parent 5bcc6caf
...@@ -95,6 +95,10 @@ struct dev_list_flag {}; ...@@ -95,6 +95,10 @@ struct dev_list_flag {};
cl::desc("Exit with success status, even if errors found"), \ cl::desc("Exit with success status, even if errors found"), \
cl::init(false)) \ cl::init(false)) \
\ \
X(AggressiveLea, bool, dev_opt_flag, "aggressive-lea", \
cl::desc("Convert additions to lea when it reduces code size"), \
cl::init(false)) \
\
X(BitcodeAsText, bool, dev_opt_flag, "bitcode-as-text", \ X(BitcodeAsText, bool, dev_opt_flag, "bitcode-as-text", \
cl::desc("Accept textual form of PNaCl bitcode " \ cl::desc("Accept textual form of PNaCl bitcode " \
"records (i.e. not .ll assembly)"), \ "records (i.e. not .ll assembly)"), \
......
...@@ -622,6 +622,13 @@ template <typename TraitsType> struct InstImpl { ...@@ -622,6 +622,13 @@ template <typename TraitsType> struct InstImpl {
Type Ty = Var->getType(); Type Ty = Var->getType();
const Operand *Src = this->getSrc(0); const Operand *Src = this->getSrc(0);
constexpr bool IsLea = K == InstX86Base::Lea; constexpr bool IsLea = K == InstX86Base::Lea;
if (IsLea) {
if (auto *Add = deoptLeaToAddOrNull(Func)) {
Add->emitIAS(Func);
return;
}
}
emitIASRegOpTyGPR(Func, IsLea, Ty, Var, Src, Emitter); emitIASRegOpTyGPR(Func, IsLea, Ty, Var, Src, Emitter);
} }
void dump(const Cfg *Func) const override { void dump(const Cfg *Func) const override {
...@@ -632,6 +639,7 @@ template <typename TraitsType> struct InstImpl { ...@@ -632,6 +639,7 @@ template <typename TraitsType> struct InstImpl {
Str << " = " << Opcode << "." << this->getSrc(0)->getType() << " "; Str << " = " << Opcode << "." << this->getSrc(0)->getType() << " ";
this->dumpSources(Func); this->dumpSources(Func);
} }
static bool classof(const Inst *Instr) { static bool classof(const Inst *Instr) {
return InstX86Base::isClassof(Instr, InstX86Base::K); return InstX86Base::isClassof(Instr, InstX86Base::K);
} }
...@@ -642,6 +650,23 @@ template <typename TraitsType> struct InstImpl { ...@@ -642,6 +650,23 @@ template <typename TraitsType> struct InstImpl {
this->addSource(Src); this->addSource(Src);
} }
Inst *deoptLeaToAddOrNull(const Cfg *Func) const {
// Revert back to Add when the Lea is a 2-address instruction.
// Caller has to emit, this just produces the add instruction.
if (auto *MemOp = llvm::dyn_cast<X86OperandMem>(this->getSrc(0))) {
if (getFlags().getAggressiveLea() &&
MemOp->getBase()->getRegNum() == this->getDest()->getRegNum() &&
MemOp->getIndex() == nullptr && MemOp->getShift() == 0) {
auto *Add = InstImpl<TraitsType>::InstX86Add::create(
const_cast<Cfg *>(Func), this->getDest(), MemOp->getOffset());
// TODO(manasijm): Remove const_cast by emitting code for add
// directly.
return Add;
}
}
return nullptr;
}
static const char *Opcode; static const char *Opcode;
static const GPREmitterRegOp Emitter; static const GPREmitterRegOp Emitter;
}; };
......
...@@ -2025,6 +2025,11 @@ template <typename TraitsType> ...@@ -2025,6 +2025,11 @@ template <typename TraitsType>
void InstImpl<TraitsType>::InstX86Lea::emit(const Cfg *Func) const { void InstImpl<TraitsType>::InstX86Lea::emit(const Cfg *Func) const {
if (!BuildDefs::dump()) if (!BuildDefs::dump())
return; return;
if (auto *Add = this->deoptLeaToAddOrNull(Func)) {
Add->emit(Func);
return;
}
Ostream &Str = Func->getContext()->getStrEmit(); Ostream &Str = Func->getContext()->getStrEmit();
assert(this->getSrcSize() == 1); assert(this->getSrcSize() == 1);
assert(this->getDest()->hasReg()); assert(this->getDest()->hasReg());
......
...@@ -2187,11 +2187,25 @@ void TargetX86Base<TraitsType>::lowerArithmetic(const InstArithmetic *Instr) { ...@@ -2187,11 +2187,25 @@ void TargetX86Base<TraitsType>::lowerArithmetic(const InstArithmetic *Instr) {
case InstArithmetic::_num: case InstArithmetic::_num:
llvm_unreachable("Unknown arithmetic operator"); llvm_unreachable("Unknown arithmetic operator");
break; break;
case InstArithmetic::Add: case InstArithmetic::Add: {
const bool ValidType =
Ty == IceType_i32 || (Ty == IceType_i64 && Traits::Is64Bit);
auto *Const = llvm::dyn_cast<Constant>(Instr->getSrc(1));
const bool ValidKind =
Const != nullptr && (llvm::isa<ConstantInteger32>(Const) ||
llvm::isa<ConstantRelocatable>(Const));
if (getFlags().getAggressiveLea() && ValidType && ValidKind) {
auto *Var = legalizeToReg(Src0);
auto *Mem = Traits::X86OperandMem::create(Func, IceType_void, Var, Const);
T = makeReg(Ty);
_lea(T, _sandbox_mem_reference(Mem));
_mov(Dest, T);
break;
}
_mov(T, Src0); _mov(T, Src0);
_add(T, Src1); _add(T, Src1);
_mov(Dest, T); _mov(Dest, T);
break; } break;
case InstArithmetic::And: case InstArithmetic::And:
_mov(T, Src0); _mov(T, Src0);
_and(T, Src1); _and(T, Src1);
......
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