Commit a91c3411 by Jim Stichnoth

Subzero: Improve non-MINIMAL string performance.

In a DUMP-enabled build, such as the standard Release+Asserts build, translator performance has regressed as a result of 467ffe51 (https://codereview.chromium.org/1838753002). This is because Variable and CfgNode names are being instantiated unconditionally, rather than on-demand. This CL restores most of that performance by going back to being on-demand. Note that it should have no effect on MINIMAL build performance. Also, it turns out that Variable::getName() does not really need the Cfg* parameter, so that is removed (and all its callers are fixed transitively). In addition, Variable and CfgNode are made more uniform with respect to each other in terms of inline definitions of the ctor, getName(), and setName(). BUG= none R=jpp@chromium.org, kschimpf@google.com Review URL: https://codereview.chromium.org/1866463002 .
parent 03077211
...@@ -1062,7 +1062,7 @@ void Cfg::emit() { ...@@ -1062,7 +1062,7 @@ void Cfg::emit() {
if (getFlags().getDecorateAsm()) { if (getFlags().getDecorateAsm()) {
for (Variable *Var : getVariables()) { for (Variable *Var : getVariables()) {
if (Var->getStackOffset() && !Var->isRematerializable()) { if (Var->getStackOffset() && !Var->isRematerializable()) {
Str << "\t" << Var->getSymbolicStackOffset(this) << " = " Str << "\t" << Var->getSymbolicStackOffset() << " = "
<< Var->getStackOffset() << "\n"; << Var->getStackOffset() << "\n";
} }
} }
......
...@@ -26,15 +26,6 @@ ...@@ -26,15 +26,6 @@
namespace Ice { namespace Ice {
CfgNode::CfgNode(Cfg *Func, SizeT Number) : Func(Func), Number(Number) {
if (BuildDefs::dump()) {
Name =
NodeString::createWithString(Func, "__" + std::to_string(getIndex()));
} else {
Name = NodeString::createWithoutString(Func);
}
}
// Adds an instruction to either the Phi list or the regular instruction list. // Adds an instruction to either the Phi list or the regular instruction list.
// Validates that all Phis are added before all regular instructions. // Validates that all Phis are added before all regular instructions.
void CfgNode::appendInst(Inst *Instr, bool AllowPhisAnywhere) { void CfgNode::appendInst(Inst *Instr, bool AllowPhisAnywhere) {
...@@ -797,7 +788,7 @@ bool CfgNode::livenessValidateIntervals(Liveness *Liveness) const { ...@@ -797,7 +788,7 @@ bool CfgNode::livenessValidateIntervals(Liveness *Liveness) const {
auto Next = Start + 1; auto Next = Start + 1;
Str << "Duplicate LR begin, block " << getName() << ", instructions " Str << "Duplicate LR begin, block " << getName() << ", instructions "
<< Start->second << " & " << Next->second << ", variable " << Start->second << " & " << Next->second << ", variable "
<< Liveness->getVariable(Start->first, this)->getName(Func) << "\n"; << Liveness->getVariable(Start->first, this)->getName() << "\n";
} }
for (auto Start = MapEnd.begin(); for (auto Start = MapEnd.begin();
(Start = std::adjacent_find(Start, MapEnd.end(), ComparePair)) != (Start = std::adjacent_find(Start, MapEnd.end(), ComparePair)) !=
...@@ -806,7 +797,7 @@ bool CfgNode::livenessValidateIntervals(Liveness *Liveness) const { ...@@ -806,7 +797,7 @@ bool CfgNode::livenessValidateIntervals(Liveness *Liveness) const {
auto Next = Start + 1; auto Next = Start + 1;
Str << "Duplicate LR end, block " << getName() << ", instructions " Str << "Duplicate LR end, block " << getName() << ", instructions "
<< Start->second << " & " << Next->second << ", variable " << Start->second << " & " << Next->second << ", variable "
<< Liveness->getVariable(Start->first, this)->getName(Func) << "\n"; << Liveness->getVariable(Start->first, this)->getName() << "\n";
} }
} }
...@@ -1402,7 +1393,7 @@ void CfgNode::dump(Cfg *Func) const { ...@@ -1402,7 +1393,7 @@ void CfgNode::dump(Cfg *Func) const {
for (SizeT i = 0; i < LiveIn.size(); ++i) { for (SizeT i = 0; i < LiveIn.size(); ++i) {
if (LiveIn[i]) { if (LiveIn[i]) {
Variable *Var = Liveness->getVariable(i, this); Variable *Var = Liveness->getVariable(i, this);
Str << " %" << Var->getName(Func); Str << " %" << Var->getName();
if (Func->isVerbose(IceV_RegOrigins) && Var->hasReg()) { if (Func->isVerbose(IceV_RegOrigins) && Var->hasReg()) {
Str << ":" Str << ":"
<< Func->getTarget()->getRegName(Var->getRegNum(), << Func->getTarget()->getRegName(Var->getRegNum(),
...@@ -1428,7 +1419,7 @@ void CfgNode::dump(Cfg *Func) const { ...@@ -1428,7 +1419,7 @@ void CfgNode::dump(Cfg *Func) const {
for (SizeT i = 0; i < LiveOut.size(); ++i) { for (SizeT i = 0; i < LiveOut.size(); ++i) {
if (LiveOut[i]) { if (LiveOut[i]) {
Variable *Var = Liveness->getVariable(i, this); Variable *Var = Liveness->getVariable(i, this);
Str << " %" << Var->getName(Func); Str << " %" << Var->getName();
if (Func->isVerbose(IceV_RegOrigins) && Var->hasReg()) { if (Func->isVerbose(IceV_RegOrigins) && Var->hasReg()) {
Str << ":" Str << ":"
<< Func->getTarget()->getRegName(Var->getRegNum(), << Func->getTarget()->getRegName(Var->getRegNum(),
......
...@@ -37,7 +37,11 @@ public: ...@@ -37,7 +37,11 @@ public:
/// Access the label number and name for this node. /// Access the label number and name for this node.
SizeT getIndex() const { return Number; } SizeT getIndex() const { return Number; }
void resetIndex(SizeT NewNumber) { Number = NewNumber; } void resetIndex(SizeT NewNumber) { Number = NewNumber; }
NodeString getName() const { return Name; } std::string getName() const {
if (Name.hasStdString())
return Name.toString();
return "__" + std::to_string(NumberOrig);
}
void setName(const std::string &NewName) { void setName(const std::string &NewName) {
if (NewName.empty()) if (NewName.empty())
return; return;
...@@ -118,10 +122,13 @@ public: ...@@ -118,10 +122,13 @@ public:
} }
private: private:
CfgNode(Cfg *Func, SizeT Number); CfgNode(Cfg *Func, SizeT Number)
: Func(Func), Number(Number), NumberOrig(Number),
Name(NodeString::createWithoutString(Func)) {}
bool livenessValidateIntervals(Liveness *Liveness) const; bool livenessValidateIntervals(Liveness *Liveness) const;
Cfg *const Func; Cfg *const Func;
SizeT Number; /// invariant: Func->Nodes[Number]==this SizeT Number; /// invariant: Func->Nodes[Number]==this
const SizeT NumberOrig; /// used for name auto-generation
NodeString Name; NodeString Name;
SizeT LoopNestDepth = 0; /// the loop nest depth of this node SizeT LoopNestDepth = 0; /// the loop nest depth of this node
bool HasReturn = false; /// does this block need an epilog? bool HasReturn = false; /// does this block need an epilog?
......
...@@ -452,7 +452,7 @@ Inst *InstPhi::lower(Cfg *Func) { ...@@ -452,7 +452,7 @@ Inst *InstPhi::lower(Cfg *Func) {
assert(Dest); assert(Dest);
Variable *NewSrc = Func->makeVariable(Dest->getType()); Variable *NewSrc = Func->makeVariable(Dest->getType());
if (BuildDefs::dump()) if (BuildDefs::dump())
NewSrc->setName(Func, Dest->getName(Func) + "_phi"); NewSrc->setName(Func, Dest->getName() + "_phi");
if (auto *NewSrc64On32 = llvm::dyn_cast<Variable64On32>(NewSrc)) if (auto *NewSrc64On32 = llvm::dyn_cast<Variable64On32>(NewSrc))
NewSrc64On32->initHiLo(Func); NewSrc64On32->initHiLo(Func);
this->Dest = NewSrc; this->Dest = NewSrc;
......
...@@ -191,12 +191,6 @@ void LiveRange::trim(InstNumberT Lower) { ...@@ -191,12 +191,6 @@ void LiveRange::trim(InstNumberT Lower) {
++TrimmedBegin; ++TrimmedBegin;
} }
std::string Variable::getName(const Cfg *Func) const {
if (Func == nullptr)
return "__" + std::to_string(getIndex());
return Name.toString();
}
const Variable *Variable::asType(const Cfg *Func, Type Ty, const Variable *Variable::asType(const Cfg *Func, Type Ty,
RegNumT NewRegNum) const { RegNumT NewRegNum) const {
// Note: This returns a Variable, even if the "this" object is a subclass of // Note: This returns a Variable, even if the "this" object is a subclass of
...@@ -539,12 +533,12 @@ void Variable::dump(const Cfg *Func, Ostream &Str) const { ...@@ -539,12 +533,12 @@ void Variable::dump(const Cfg *Func, Ostream &Str) const {
if (!BuildDefs::dump()) if (!BuildDefs::dump())
return; return;
if (Func == nullptr) { if (Func == nullptr) {
Str << "%" << getName(Func); Str << "%" << getName();
return; return;
} }
if (Func->isVerbose(IceV_RegOrigins) || if (Func->isVerbose(IceV_RegOrigins) ||
(!hasReg() && !Func->getTarget()->hasComputedFrame())) (!hasReg() && !Func->getTarget()->hasComputedFrame()))
Str << "%" << getName(Func); Str << "%" << getName();
if (hasReg()) { if (hasReg()) {
if (Func->isVerbose(IceV_RegOrigins)) if (Func->isVerbose(IceV_RegOrigins))
Str << ":"; Str << ":";
......
...@@ -647,9 +647,12 @@ public: ...@@ -647,9 +647,12 @@ public:
} }
SizeT getIndex() const { return Number; } SizeT getIndex() const { return Number; }
std::string getName(const Cfg *Func) const; std::string getName() const {
if (Name.hasStdString())
return Name.toString();
return "__" + std::to_string(getIndex());
}
virtual void setName(const Cfg *Func, const std::string &NewName) { virtual void setName(const Cfg *Func, const std::string &NewName) {
(void)Func;
if (NewName.empty()) if (NewName.empty())
return; return;
Name = VariableString::createWithString(Func, NewName); Name = VariableString::createWithString(Func, NewName);
...@@ -669,10 +672,10 @@ public: ...@@ -669,10 +672,10 @@ public:
void setStackOffset(int32_t Offset) { StackOffset = Offset; } void setStackOffset(int32_t Offset) { StackOffset = Offset; }
/// Returns the variable's stack offset in symbolic form, to improve /// Returns the variable's stack offset in symbolic form, to improve
/// readability in DecorateAsm mode. /// readability in DecorateAsm mode.
std::string getSymbolicStackOffset(const Cfg *Func) const { std::string getSymbolicStackOffset() const {
if (!BuildDefs::dump()) if (!BuildDefs::dump())
return ""; return "";
return "lv$" + getName(Func); return "lv$" + getName();
} }
bool hasReg() const { return getRegNum().hasValue(); } bool hasReg() const { return getRegNum().hasValue(); }
...@@ -755,12 +758,6 @@ protected: ...@@ -755,12 +758,6 @@ protected:
Vars = VarsReal; Vars = VarsReal;
Vars[0] = this; Vars[0] = this;
NumVars = 1; NumVars = 1;
if (BuildDefs::dump()) {
Name = VariableString::createWithString(
Func, "__" + std::to_string(getIndex()));
} else {
Name = VariableString::createWithoutString(Func);
}
} }
/// Number is unique across all variables, and is used as a (bit)vector index /// Number is unique across all variables, and is used as a (bit)vector index
/// for liveness analysis. /// for liveness analysis.
...@@ -805,8 +802,8 @@ public: ...@@ -805,8 +802,8 @@ public:
void setName(const Cfg *Func, const std::string &NewName) override { void setName(const Cfg *Func, const std::string &NewName) override {
Variable::setName(Func, NewName); Variable::setName(Func, NewName);
if (LoVar && HiVar) { if (LoVar && HiVar) {
LoVar->setName(Func, getName(Func) + "__lo"); LoVar->setName(Func, getName() + "__lo");
HiVar->setName(Func, getName(Func) + "__hi"); HiVar->setName(Func, getName() + "__hi");
} }
} }
...@@ -835,8 +832,8 @@ public: ...@@ -835,8 +832,8 @@ public:
LoVar->setIsArg(getIsArg()); LoVar->setIsArg(getIsArg());
HiVar->setIsArg(getIsArg()); HiVar->setIsArg(getIsArg());
if (BuildDefs::dump()) { if (BuildDefs::dump()) {
LoVar->setName(Func, getName(Func) + "__lo"); LoVar->setName(Func, getName() + "__lo");
HiVar->setName(Func, getName(Func) + "__hi"); HiVar->setName(Func, getName() + "__hi");
} }
} }
......
...@@ -169,12 +169,12 @@ bool LinearScan::livenessValidateIntervals( ...@@ -169,12 +169,12 @@ bool LinearScan::livenessValidateIntervals(
for (SizeT VarNum : DefsWithoutUses) { for (SizeT VarNum : DefsWithoutUses) {
Variable *Var = Vars[VarNum]; Variable *Var = Vars[VarNum];
Str << "LR def without use, instruction " << LRBegin[VarNum] Str << "LR def without use, instruction " << LRBegin[VarNum]
<< ", variable " << Var->getName(Func) << "\n"; << ", variable " << Var->getName() << "\n";
} }
for (SizeT VarNum : UsesBeforeDefs) { for (SizeT VarNum : UsesBeforeDefs) {
Variable *Var = Vars[VarNum]; Variable *Var = Vars[VarNum];
Str << "LR use before def, instruction " << LREnd[VarNum] << ", variable " Str << "LR use before def, instruction " << LREnd[VarNum] << ", variable "
<< Var->getName(Func) << "\n"; << Var->getName() << "\n";
} }
return false; return false;
} }
...@@ -277,12 +277,12 @@ void LinearScan::initForInfOnly() { ...@@ -277,12 +277,12 @@ void LinearScan::initForInfOnly() {
for (SizeT VarNum : DefsWithoutUses) { for (SizeT VarNum : DefsWithoutUses) {
Variable *Var = Vars[VarNum]; Variable *Var = Vars[VarNum];
Str << "LR def without use, instruction " << LRBegin[VarNum] Str << "LR def without use, instruction " << LRBegin[VarNum]
<< ", variable " << Var->getName(Func) << "\n"; << ", variable " << Var->getName() << "\n";
} }
for (SizeT VarNum : UsesBeforeDefs) { for (SizeT VarNum : UsesBeforeDefs) {
Variable *Var = Vars[VarNum]; Variable *Var = Vars[VarNum];
Str << "LR use before def, instruction " << LREnd[VarNum] Str << "LR use before def, instruction " << LREnd[VarNum]
<< ", variable " << Var->getName(Func) << "\n"; << ", variable " << Var->getName() << "\n";
} }
} }
llvm::report_fatal_error("initForInfOnly: Liveness error"); llvm::report_fatal_error("initForInfOnly: Liveness error");
...@@ -715,7 +715,7 @@ void LinearScan::handleNoFreeRegisters(IterationState &Iter) { ...@@ -715,7 +715,7 @@ void LinearScan::handleNoFreeRegisters(IterationState &Iter) {
Func->setError("Unable to find a physical register for an " Func->setError("Unable to find a physical register for an "
"infinite-weight live range " "infinite-weight live range "
"(consider using -reg-reserve): " + "(consider using -reg-reserve): " +
Iter.Cur->getName(Func)); Iter.Cur->getName());
Handled.push_back(Iter.Cur); Handled.push_back(Iter.Cur);
return; return;
} }
......
...@@ -1270,7 +1270,7 @@ void TargetARM32::emitVariable(const Variable *Var) const { ...@@ -1270,7 +1270,7 @@ void TargetARM32::emitVariable(const Variable *Var) const {
return; return;
} }
if (Var->mustHaveReg()) { if (Var->mustHaveReg()) {
llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName() +
") has no register assigned - function " + ") has no register assigned - function " +
Func->getFunctionName()); Func->getFunctionName());
} }
...@@ -1402,7 +1402,7 @@ void TargetARM32::lowerArguments() { ...@@ -1402,7 +1402,7 @@ void TargetARM32::lowerArguments() {
Variable *RegisterArg = Func->makeVariable(Ty); Variable *RegisterArg = Func->makeVariable(Ty);
if (BuildDefs::dump()) { if (BuildDefs::dump()) {
RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); RegisterArg->setName(Func, "home_reg:" + Arg->getName());
} }
RegisterArg->setIsArg(); RegisterArg->setIsArg();
Arg->setIsArg(false); Arg->setIsArg(false);
......
...@@ -434,7 +434,7 @@ void TargetMIPS32::lowerArguments() { ...@@ -434,7 +434,7 @@ void TargetMIPS32::lowerArguments() {
Variable *RegisterArg = Func->makeVariable(Ty); Variable *RegisterArg = Func->makeVariable(Ty);
auto *RegisterArg64On32 = llvm::cast<Variable64On32>(RegisterArg); auto *RegisterArg64On32 = llvm::cast<Variable64On32>(RegisterArg);
if (BuildDefs::dump()) if (BuildDefs::dump())
RegisterArg64On32->setName(Func, "home_reg:" + Arg->getName(Func)); RegisterArg64On32->setName(Func, "home_reg:" + Arg->getName());
RegisterArg64On32->initHiLo(Func); RegisterArg64On32->initHiLo(Func);
RegisterArg64On32->setIsArg(); RegisterArg64On32->setIsArg();
RegisterArg64On32->getLo()->setRegNum(RegLo); RegisterArg64On32->getLo()->setRegNum(RegLo);
...@@ -451,7 +451,7 @@ void TargetMIPS32::lowerArguments() { ...@@ -451,7 +451,7 @@ void TargetMIPS32::lowerArguments() {
++NumGPRRegsUsed; ++NumGPRRegsUsed;
Variable *RegisterArg = Func->makeVariable(Ty); Variable *RegisterArg = Func->makeVariable(Ty);
if (BuildDefs::dump()) { if (BuildDefs::dump()) {
RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); RegisterArg->setName(Func, "home_reg:" + Arg->getName());
} }
RegisterArg->setRegNum(RegNum); RegisterArg->setRegNum(RegNum);
RegisterArg->setIsArg(); RegisterArg->setIsArg();
......
...@@ -886,7 +886,7 @@ void TargetX86Base<TraitsType>::emitVariable(const Variable *Var) const { ...@@ -886,7 +886,7 @@ void TargetX86Base<TraitsType>::emitVariable(const Variable *Var) const {
return; return;
} }
if (Var->mustHaveReg()) { if (Var->mustHaveReg()) {
llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName() +
") has no register assigned - function " + ") has no register assigned - function " +
Func->getFunctionName()); Func->getFunctionName());
} }
...@@ -901,7 +901,7 @@ void TargetX86Base<TraitsType>::emitVariable(const Variable *Var) const { ...@@ -901,7 +901,7 @@ void TargetX86Base<TraitsType>::emitVariable(const Variable *Var) const {
// Only print Offset when it is nonzero, regardless of DecorateAsm. // Only print Offset when it is nonzero, regardless of DecorateAsm.
if (Offset) { if (Offset) {
if (DecorateAsm) { if (DecorateAsm) {
Str << Var->getSymbolicStackOffset(Func); Str << Var->getSymbolicStackOffset();
} else { } else {
Str << Offset; Str << Offset;
} }
...@@ -916,7 +916,7 @@ TargetX86Base<TraitsType>::stackVarToAsmOperand(const Variable *Var) const { ...@@ -916,7 +916,7 @@ TargetX86Base<TraitsType>::stackVarToAsmOperand(const Variable *Var) const {
if (Var->hasReg()) if (Var->hasReg())
llvm::report_fatal_error("Stack Variable has a register assigned"); llvm::report_fatal_error("Stack Variable has a register assigned");
if (Var->mustHaveReg()) { if (Var->mustHaveReg()) {
llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName() +
") has no register assigned - function " + ") has no register assigned - function " +
Func->getFunctionName()); Func->getFunctionName());
} }
...@@ -1509,7 +1509,7 @@ void TargetX86Base<TraitsType>::lowerArguments() { ...@@ -1509,7 +1509,7 @@ void TargetX86Base<TraitsType>::lowerArguments() {
// an instruction in the prolog to copy the home register to the assigned // an instruction in the prolog to copy the home register to the assigned
// location of Arg. // location of Arg.
if (BuildDefs::dump()) if (BuildDefs::dump())
RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); RegisterArg->setName(Func, "home_reg:" + Arg->getName());
RegisterArg->setRegNum(RegNum); RegisterArg->setRegNum(RegNum);
RegisterArg->setIsArg(); RegisterArg->setIsArg();
Arg->setIsArg(false); Arg->setIsArg(false);
......
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