Rematerialize ALU+IMM operations on ARM (bug 555255 r=jbramley+)

The ARM backend already supported single-instruction folding of immediates into
add/sub/and/or/xor instructions.  This patch enables the same instructions to
be rematerialized without spilling them.

--HG--
extra : convert_revision : c5fca9078e37d7d79f66cf6023fcbf707d11d57b
This commit is contained in:
Edwin Smith 2010-04-27 09:38:27 -04:00
Родитель ad50b202ee
Коммит 617d47bec1
1 изменённых файлов: 30 добавлений и 3 удалений

Просмотреть файл

@ -1230,10 +1230,28 @@ Assembler::asm_store32(LOpcode op, LIns *value, int dr, LIns *base)
}
}
bool
canRematALU(LIns *ins)
{
// Return true if we can generate code for this instruction that neither
// sets CCs, clobbers an input register, nor requires allocating a register.
switch (ins->opcode()) {
case LIR_addi:
case LIR_subi:
case LIR_andi:
case LIR_ori:
case LIR_xori:
return ins->oprnd1()->isInReg() && ins->oprnd2()->isImmI();
default:
;
}
return false;
}
bool
Assembler::canRemat(LIns* ins)
{
return ins->isImmI() || ins->isop(LIR_alloc);
return ins->isImmI() || ins->isop(LIR_alloc) || canRematALU(ins);
}
void
@ -1243,8 +1261,17 @@ Assembler::asm_restore(LInsp i, Register r)
asm_add_imm(r, FP, deprecated_disp(i));
} else if (i->isImmI()) {
asm_ld_imm(r, i->immI());
} else if (canRematALU(i)) {
Register rn = i->oprnd1()->getReg();
int32_t imm = i->oprnd2()->immI();
switch (i->opcode()) {
case LIR_addi: asm_add_imm(r, rn, imm, /*stat=*/ 0); break;
case LIR_subi: asm_sub_imm(r, rn, imm, /*stat=*/ 0); break;
case LIR_andi: asm_and_imm(r, rn, imm, /*stat=*/ 0); break;
case LIR_ori: asm_orr_imm(r, rn, imm, /*stat=*/ 0); break;
case LIR_xori: asm_eor_imm(r, rn, imm, /*stat=*/ 0); break;
}
else {
} else {
// We can't easily load immediate values directly into FP registers, so
// ensure that memory is allocated for the constant and load it from
// memory.