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
diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp
index ed962d1..04e7acd 100644
--- a/src/IceCfg.cpp
+++ b/src/IceCfg.cpp
@@ -284,6 +284,19 @@
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) {
diff --git a/src/IceCfg.h b/src/IceCfg.h
index 606f785..93aa159 100644
--- a/src/IceCfg.h
+++ b/src/IceCfg.h
@@ -119,6 +119,7 @@
void livenessLightweight();
void liveness(LivenessMode Mode);
bool validateLiveness() const;
+ void deleteRedundantAssignments();
void doBranchOpt();
// Manage the CurrentNode field, which is used for validating the
diff --git a/src/IceCfgNode.cpp b/src/IceCfgNode.cpp
index d715767..a1804d5 100644
--- a/src/IceCfgNode.cpp
+++ b/src/IceCfgNode.cpp
@@ -506,10 +506,6 @@
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 {
diff --git a/src/IceCfgNode.h b/src/IceCfgNode.h
index 97ce69c..031c76c 100644
--- a/src/IceCfgNode.h
+++ b/src/IceCfgNode.h
@@ -52,6 +52,7 @@
// 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
diff --git a/src/IceClFlags.h b/src/IceClFlags.h
index d610c6a..eebca45 100644
--- a/src/IceClFlags.h
+++ b/src/IceClFlags.h
@@ -27,7 +27,7 @@
UseIntegratedAssembler(false), UseSandboxing(false), DumpStats(false),
AllowUninitializedGlobals(false), TimeEachFunction(false),
DefaultGlobalPrefix(""), DefaultFunctionPrefix(""), TimingFocusOn(""),
- VerboseFocusOn("") {}
+ VerboseFocusOn(""), TranslateOnly("") {}
bool DisableInternal;
bool SubzeroTimingEnabled;
bool DisableTranslation;
diff --git a/src/IceInst.h b/src/IceInst.h
index bbd817b..0a47e1a 100644
--- a/src/IceInst.h
+++ b/src/IceInst.h
@@ -554,6 +554,7 @@
}
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);
diff --git a/src/IceInstX8632.h b/src/IceInstX8632.h
index 81d3fd8..1778437 100644
--- a/src/IceInstX8632.h
+++ b/src/IceInstX8632.h
@@ -342,6 +342,7 @@
// 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 @@
// 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>())
diff --git a/src/IceTargetLowering.cpp b/src/IceTargetLowering.cpp
index bcc6290..b18999f 100644
--- a/src/IceTargetLowering.cpp
+++ b/src/IceTargetLowering.cpp
@@ -54,6 +54,7 @@
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::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) {
diff --git a/src/IceTargetLowering.h b/src/IceTargetLowering.h
index 6e172a2..e46399d 100644
--- a/src/IceTargetLowering.h
+++ b/src/IceTargetLowering.h
@@ -39,7 +39,7 @@
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 @@
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 @@
void skipDeleted(InstList::iterator &I) const;
void advanceForward(InstList::iterator &I) const;
- void advanceBackward(InstList::iterator &I) const;
};
class TargetLowering {
@@ -145,8 +145,10 @@
// 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;
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index 8ea5882..8082c52 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -384,6 +384,8 @@
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 @@
return;
Func->dump("After stack frame mapping");
+ Func->deleteRedundantAssignments();
+
// Nop insertion
if (shouldDoNopInsertion()) {
Func->doNopInsertion();
@@ -444,11 +448,13 @@
#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
diff --git a/src/IceTargetLoweringX8632.h b/src/IceTargetLoweringX8632.h
index 20d7150..88b75ac 100644
--- a/src/IceTargetLoweringX8632.h
+++ b/src/IceTargetLoweringX8632.h
@@ -35,7 +35,7 @@
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;