Subzero: Simplify the FakeKill instruction.
Even after earlier simplifications, FakeKill was still handled somewhat inefficiently for the register allocator. For x86-32, any function containing call instructions would result in about 11 pre-colored Variables, each with an identical and relatively complex live range consisting of points. They would start out on the UnhandledPrecolored list, then all move to the Inactive list, where they would be repeatedly compared against each register allocation candidate via overlapsRange().
We improve this by keeping around a single copy of that live range and directly masking out the Free[] register set when that live range overlaps the current candidate's live range. This saves ~10 overlaps() calculations per candidate while FakeKills are still pending.
Also, slightly rearrange the initialization of the Unhandled etc. sets into a separate init routine, which will make it easier to reuse the register allocator in other situations such as Om1 post-lowering.
BUG= none
R=jvoung@chromium.org
Review URL: https://codereview.chromium.org/720343003
diff --git a/src/IceInst.h b/src/IceInst.h
index 71da0b3..5d5101b 100644
--- a/src/IceInst.h
+++ b/src/IceInst.h
@@ -782,11 +782,12 @@
~InstFakeUse() override {}
};
-// FakeKill instruction. This "kills" a set of variables by adding a
-// trivial live range at this instruction to each variable. The
-// primary use is to indicate that scratch registers are killed after
-// a call, so that the register allocator won't assign a scratch
-// register to a variable whose live range spans a call.
+// FakeKill instruction. This "kills" a set of variables by modeling
+// a trivial live range at this instruction for each (implicit)
+// variable. The primary use is to indicate that scratch registers
+// are killed after a call, so that the register allocator won't
+// assign a scratch register to a variable whose live range spans a
+// call.
//
// The FakeKill instruction also holds a pointer to the instruction
// that kills the set of variables, so that if that linked instruction
@@ -796,12 +797,9 @@
InstFakeKill &operator=(const InstFakeKill &) = delete;
public:
- static InstFakeKill *create(Cfg *Func, const VarList &KilledRegs,
- const Inst *Linked) {
- return new (Func->allocateInst<InstFakeKill>())
- InstFakeKill(Func, KilledRegs, Linked);
+ static InstFakeKill *create(Cfg *Func, const Inst *Linked) {
+ return new (Func->allocateInst<InstFakeKill>()) InstFakeKill(Func, Linked);
}
- const VarList &getKilledRegs() const { return KilledRegs; }
const Inst *getLinked() const { return Linked; }
void emit(const Cfg *Func) const override;
void emitIAS(const Cfg * /* Func */) const override {}
@@ -809,10 +807,9 @@
static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; }
private:
- InstFakeKill(Cfg *Func, const VarList &KilledRegs, const Inst *Linked);
+ InstFakeKill(Cfg *Func, const Inst *Linked);
~InstFakeKill() override {}
- const VarList &KilledRegs;
// This instruction is ignored if Linked->isDeleted() is true.
const Inst *Linked;
};