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