Commit 98712a39 by Jim Stichnoth

Subzero: Minor refactoring/additions in preparation for phi edge splitting.

The only functional change (though not actually visible at this point) is that redundant assignment elimination is moved into a separate pass. BUG= none R=jvoung@chromium.org Review URL: https://codereview.chromium.org/672393003
parent 7e1e4857
......@@ -284,6 +284,19 @@ bool Cfg::validateLiveness() const {
return Valid;
}
// Deletes redundant assignments like "var=var". This includes
// architecturally redundant moves like "var1:eax=var2:eax". As such,
// this needs to be done very late in the translation to avoid
// liveness inconsistencies.
void Cfg::deleteRedundantAssignments() {
for (CfgNode *Node : Nodes) {
// Ignore Phi instructions.
for (Inst *I : Node->getInsts())
if (I->isRedundantAssign())
I->setDeleted();
}
}
void Cfg::doBranchOpt() {
TimerMarker T(TimerStack::TT_doBranchOpt, this);
for (auto I = Nodes.begin(), E = Nodes.end(); I != E; ++I) {
......
......@@ -119,6 +119,7 @@ public:
void livenessLightweight();
void liveness(LivenessMode Mode);
bool validateLiveness() const;
void deleteRedundantAssignments();
void doBranchOpt();
// Manage the CurrentNode field, which is used for validating the
......
......@@ -506,10 +506,6 @@ void CfgNode::emit(Cfg *Func) const {
for (Inst *I : Insts) {
if (I->isDeleted())
continue;
// Here we detect redundant assignments like "mov eax, eax" and
// suppress them.
if (I->isRedundantAssign())
continue;
if (Func->useIntegratedAssembler()) {
I->emitIAS(Func);
} else {
......
......@@ -52,6 +52,7 @@ public:
// Manage the instruction list.
InstList &getInsts() { return Insts; }
PhiList &getPhis() { return Phis; }
void appendInst(Inst *Inst);
void renumberInstructions();
// Rough and generally conservative estimate of the number of
......
......@@ -27,7 +27,7 @@ public:
UseIntegratedAssembler(false), UseSandboxing(false), DumpStats(false),
AllowUninitializedGlobals(false), TimeEachFunction(false),
DefaultGlobalPrefix(""), DefaultFunctionPrefix(""), TimingFocusOn(""),
VerboseFocusOn("") {}
VerboseFocusOn(""), TranslateOnly("") {}
bool DisableInternal;
bool SubzeroTimingEnabled;
bool DisableTranslation;
......
......@@ -554,6 +554,7 @@ public:
}
void addArgument(Operand *Source, CfgNode *Label);
Operand *getOperandForTarget(CfgNode *Target) const;
CfgNode *getLabel(SizeT Index) const { return Labels[Index]; }
void livenessPhiOperand(LivenessBV &Live, CfgNode *Target,
Liveness *Liveness);
Inst *lower(Cfg *Func);
......
......@@ -342,6 +342,7 @@ public:
// Create a conditional branch to a node.
static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue,
CfgNode *TargetFalse, CondX86::BrCond Condition) {
assert(Condition != CondX86::Br_None);
const InstX8632Label *NoLabel = NULL;
return new (Func->allocate<InstX8632Br>())
InstX8632Br(Func, TargetTrue, TargetFalse, NoLabel, Condition);
......@@ -358,6 +359,7 @@ public:
// used for switch lowering.
static InstX8632Br *create(Cfg *Func, CfgNode *Target,
CondX86::BrCond Condition) {
assert(Condition != CondX86::Br_None);
const CfgNode *NoUncondTarget = NULL;
const InstX8632Label *NoLabel = NULL;
return new (Func->allocate<InstX8632Br>())
......
......@@ -54,6 +54,7 @@ void LoweringContext::init(CfgNode *N) {
void LoweringContext::insert(Inst *Inst) {
getNode()->getInsts().insert(Next, Inst);
LastInserted = Inst;
}
void LoweringContext::skipDeleted(InstList::iterator &I) const {
......@@ -68,17 +69,9 @@ void LoweringContext::advanceForward(InstList::iterator &I) const {
}
}
void LoweringContext::advanceBackward(InstList::iterator &I) const {
assert(I != Begin);
do {
--I;
} while (I != Begin && (*I)->isDeleted());
}
Inst *LoweringContext::getLastInserted() const {
InstList::iterator Cursor = Next;
advanceBackward(Cursor);
return *Cursor;
assert(LastInserted);
return LastInserted;
}
TargetLowering *TargetLowering::createLowering(TargetArch Target, Cfg *Func) {
......
......@@ -39,7 +39,7 @@ class LoweringContext {
LoweringContext &operator=(const LoweringContext &) = delete;
public:
LoweringContext() : Node(NULL) {}
LoweringContext() : Node(NULL), LastInserted(NULL) {}
~LoweringContext() {}
void init(CfgNode *Node);
Inst *getNextInst() const {
......@@ -69,6 +69,7 @@ public:
private:
// Node is the argument to Inst::updateVars().
CfgNode *Node;
Inst *LastInserted;
// Cur points to the current instruction being considered. It is
// guaranteed to point to a non-deleted instruction, or to be End.
InstList::iterator Cur;
......@@ -88,7 +89,6 @@ private:
void skipDeleted(InstList::iterator &I) const;
void advanceForward(InstList::iterator &I) const;
void advanceBackward(InstList::iterator &I) const;
};
class TargetLowering {
......@@ -145,8 +145,10 @@ public:
// Returns a variable pre-colored to the specified physical
// register. This is generally used to get very direct access to
// the register such as in the prolog or epilog or for marking
// scratch registers as killed by a call.
virtual Variable *getPhysicalRegister(SizeT RegNum) = 0;
// scratch registers as killed by a call. If a Type is not
// provided, a target-specific default type is used.
virtual Variable *getPhysicalRegister(SizeT RegNum,
Type Ty = IceType_void) = 0;
// Returns a printable name for the register.
virtual IceString getRegName(SizeT RegNum, Type Ty) const = 0;
......
......@@ -384,6 +384,8 @@ void TargetX8632::translateO2() {
return;
Func->dump("After stack frame mapping");
Func->deleteRedundantAssignments();
// Branch optimization. This needs to be done just before code
// emission. In particular, no transformations that insert or
// reorder CfgNodes should be done after branch optimization. We go
......@@ -423,6 +425,8 @@ void TargetX8632::translateOm1() {
return;
Func->dump("After stack frame mapping");
Func->deleteRedundantAssignments();
// Nop insertion
if (shouldDoNopInsertion()) {
Func->doNopInsertion();
......@@ -444,11 +448,13 @@ IceString TargetX8632::RegNames[] = {
#undef X
};
Variable *TargetX8632::getPhysicalRegister(SizeT RegNum) {
Variable *TargetX8632::getPhysicalRegister(SizeT RegNum, Type Ty) {
if (Ty == IceType_void)
Ty = IceType_i32;
assert(RegNum < PhysicalRegisters.size());
Variable *Reg = PhysicalRegisters[RegNum];
if (Reg == NULL) {
Reg = Func->makeVariable(IceType_i32);
Reg = Func->makeVariable(Ty);
Reg->setRegNum(RegNum);
PhysicalRegisters[RegNum] = Reg;
// Specially mark esp as an "argument" so that it is considered
......
......@@ -35,7 +35,7 @@ public:
void translateO2() override;
bool doBranchOpt(Inst *I, const CfgNode *NextNode) override;
Variable *getPhysicalRegister(SizeT RegNum) override;
Variable *getPhysicalRegister(SizeT RegNum, Type Ty = IceType_void) override;
IceString getRegName(SizeT RegNum, Type Ty) const override;
llvm::SmallBitVector getRegisterSet(RegSetMask Include,
RegSetMask Exclude) const override;
......
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