Commit 33c80641 by Jim Stichnoth

Subzero: Remove Variable::NeedsStackSlot.

Instead, separately compute it during prolog generation via another pass over the Cfg. This may slow down translation by ~1%, but it greatly simplifies the management of this flag/property. The higher motivation is to pull this management out of register allocation to make it easier to extend register allocation for other uses. BUG= none R=jvoung@chromium.org Review URL: https://codereview.chromium.org/692633004
parent 607e9f0e
......@@ -434,7 +434,6 @@ void CfgNode::advancedPhiLowering() {
SizeT VarNum = Func->getNumVariables();
Variable *Tmp = Func->makeVariable(
OtherSrc->getType(), "__split_" + std::to_string(VarNum));
Tmp->setNeedsStackSlot();
Assignments.push_back(InstAssign::create(Func, Tmp, OtherSrc));
Desc[J].Src = Tmp;
Found = true;
......
......@@ -405,8 +405,6 @@ public:
void setIgnoreLiveness() { IgnoreLiveness = true; }
bool getIgnoreLiveness() const { return IgnoreLiveness; }
bool needsStackSlot() const { return NeedsStackSlot; }
void setNeedsStackSlot() { NeedsStackSlot = true; }
int32_t getStackOffset() const { return StackOffset; }
void setStackOffset(int32_t Offset) { StackOffset = Offset; }
......@@ -483,9 +481,9 @@ public:
protected:
Variable(OperandKind K, Type Ty, SizeT Index, const IceString &Name)
: Operand(K, Ty), Number(Index), Name(Name), IsArgument(false),
IsImplicitArgument(false), IgnoreLiveness(false), NeedsStackSlot(false),
StackOffset(0), RegNum(NoRegister), RegNumTmp(NoRegister), Weight(1),
LoVar(NULL), HiVar(NULL) {
IsImplicitArgument(false), IgnoreLiveness(false), StackOffset(0),
RegNum(NoRegister), RegNumTmp(NoRegister), Weight(1), LoVar(NULL),
HiVar(NULL) {
Vars = VarsReal;
Vars[0] = this;
NumVars = 1;
......@@ -501,9 +499,6 @@ protected:
// constructing and validating live ranges. This is usually
// reserved for the stack pointer.
bool IgnoreLiveness;
// NeedsStackSlot starts out false, and is set to true once we know
// for sure that the variable needs a stack slot.
bool NeedsStackSlot;
// StackOffset is the canonical location on stack (only if
// RegNum==NoRegister || IsArgument).
int32_t StackOffset;
......
......@@ -105,15 +105,12 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) {
for (Variable *Var : Vars) {
// Explicitly don't consider zero-weight variables, which are
// meant to be spill slots.
if (Var->getWeight() == RegWeight::Zero) {
Var->setNeedsStackSlot();
if (Var->getWeight() == RegWeight::Zero)
continue;
}
// Don't bother if the variable has a null live range, which means
// it was never referenced.
if (Var->getLiveRange().isEmpty())
continue;
Var->setNeedsStackSlot();
Var->untrimLiveRange();
Unhandled.push_back(Var);
if (Var->hasReg()) {
......
......@@ -277,7 +277,7 @@ ICETYPE_TABLE;
TargetX8632::TargetX8632(Cfg *Func)
: TargetLowering(Func), InstructionSet(CLInstructionSet),
IsEbpBasedFrame(false), NeedsStackAlignment(false), FrameSizeLocals(0),
SpillAreaSizeBytes(0), NextLabelNumber(0), ComputedLiveRanges(false) {
SpillAreaSizeBytes(0), NextLabelNumber(0) {
// TODO: Don't initialize IntegerRegisters and friends every time.
// Instead, initialize in some sort of static initializer for the
// class.
......@@ -373,7 +373,6 @@ void TargetX8632::translateO2() {
// Validate the live range computations. The expensive validation
// call is deliberately only made when assertions are enabled.
assert(Func->validateLiveness());
ComputedLiveRanges = true;
// The post-codegen dump is done here, after liveness analysis and
// associated cleanup, to make the dump cleaner and more useful.
Func->dump("After initial x8632 codegen");
......@@ -667,6 +666,27 @@ void TargetX8632::addProlog(CfgNode *Node) {
// * LocalsSpillAreaSize: area 6
// * SpillAreaSizeBytes: areas 3 - 7
// Make a final pass over the Cfg to determine which variables need
// stack slots.
llvm::BitVector IsVarReferenced(Func->getNumVariables());
for (CfgNode *Node : Func->getNodes()) {
for (auto Inst = Node->getInsts().begin(), E = Node->getInsts().end();
Inst != E; ++Inst) {
if (Inst->isDeleted())
continue;
if (const Variable *Var = Inst->getDest())
IsVarReferenced[Var->getIndex()] = true;
for (SizeT I = 0; I < Inst->getSrcSize(); ++I) {
Operand *Src = Inst->getSrc(I);
SizeT NumVars = Src->getNumVars();
for (SizeT J = 0; J < NumVars; ++J) {
const Variable *Var = Src->getVar(J);
IsVarReferenced[Var->getIndex()] = true;
}
}
}
}
// If SimpleCoalescing is false, each variable without a register
// gets its own unique stack slot, which leads to large stack
// frames. If SimpleCoalescing is true, then each "global" variable
......@@ -726,7 +746,7 @@ void TargetX8632::addProlog(CfgNode *Node) {
if (Var->getIsArg())
continue;
// An unreferenced variable doesn't need a stack slot.
if (ComputedLiveRanges && !Var->needsStackSlot())
if (!IsVarReferenced[Var->getIndex()])
continue;
// A spill slot linked to a variable with a stack slot should reuse
// that stack slot.
......@@ -4254,7 +4274,6 @@ void TargetX8632::lowerPhiAssignments(CfgNode *Node,
RegNum = RegsForType.find_first();
Preg = getPhysicalRegister(RegNum, Dest->getType());
SpillLoc = Func->makeVariable(Dest->getType());
SpillLoc->setNeedsStackSlot();
if (IsVector)
_movp(SpillLoc, Preg);
else
......
......@@ -482,7 +482,6 @@ protected:
llvm::SmallBitVector ScratchRegs;
llvm::SmallBitVector RegsUsed;
SizeT NextLabelNumber;
bool ComputedLiveRanges;
VarList PhysicalRegisters[IceType_NUM];
VarList FakeKilledScratchRegisters;
static IceString RegNames[];
......
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