| Index: src/IceRegAlloc.cpp
|
| diff --git a/src/IceRegAlloc.cpp b/src/IceRegAlloc.cpp
|
| index d9837d967c0a63d8d87926742b0b479e760e4597..dacbc009bda6846fed013fb345dd1d7621032918 100644
|
| --- a/src/IceRegAlloc.cpp
|
| +++ b/src/IceRegAlloc.cpp
|
| @@ -132,6 +132,35 @@ void LinearScan::initForGlobal() {
|
| }
|
| }
|
|
|
| +// Validate the integrity of the live ranges. If there are any errors, it
|
| +// prints details and returns false. On success, it returns true.
|
| +bool LinearScan::livenessValidateIntervals(
|
| + const DefUseErrorList &DefsWithoutUses,
|
| + const DefUseErrorList &UsesBeforeDefs,
|
| + const CfgVector<InstNumberT> &LRBegin,
|
| + const CfgVector<InstNumberT> &LREnd) {
|
| + if (DefsWithoutUses.empty() && UsesBeforeDefs.empty())
|
| + return true;
|
| +
|
| + if (!BuildDefs::dump())
|
| + return false;
|
| +
|
| + const VarList &Vars = Func->getVariables();
|
| + OstreamLocker L(Ctx);
|
| + Ostream &Str = Ctx->getStrDump();
|
| + for (SizeT VarNum : DefsWithoutUses) {
|
| + Variable *Var = Vars[VarNum];
|
| + Str << "LR def without use, instruction " << LRBegin[VarNum]
|
| + << ", variable " << Var->getName(Func) << "\n";
|
| + }
|
| + for (SizeT VarNum : UsesBeforeDefs) {
|
| + Variable *Var = Vars[VarNum];
|
| + Str << "LR use before def, instruction " << LREnd[VarNum] << ", variable "
|
| + << Var->getName(Func) << "\n";
|
| + }
|
| + return false;
|
| +}
|
| +
|
| // Prepare for very simple register allocation of only infinite-weight
|
| // Variables while respecting pre-colored Variables. Some properties we take
|
| // advantage of:
|
| @@ -168,10 +197,21 @@ void LinearScan::initForInfOnly() {
|
| // range for each variable that is pre-colored or infinite weight.
|
| CfgVector<InstNumberT> LRBegin(Vars.size(), Inst::NumberSentinel);
|
| CfgVector<InstNumberT> LREnd(Vars.size(), Inst::NumberSentinel);
|
| + DefUseErrorList DefsWithoutUses, UsesBeforeDefs;
|
| for (CfgNode *Node : Func->getNodes()) {
|
| for (Inst &Inst : Node->getInsts()) {
|
| if (Inst.isDeleted())
|
| continue;
|
| + FOREACH_VAR_IN_INST(Var, Inst) {
|
| + if (Var->getIgnoreLiveness())
|
| + continue;
|
| + if (Var->hasReg() || Var->mustHaveReg()) {
|
| + SizeT VarNum = Var->getIndex();
|
| + LREnd[VarNum] = Inst.getNumber();
|
| + if (!Var->getIsArg() && LRBegin[VarNum] == Inst::NumberSentinel)
|
| + UsesBeforeDefs.push_back(VarNum);
|
| + }
|
| + }
|
| if (const Variable *Var = Inst.getDest()) {
|
| if (!Var->getIgnoreLiveness() &&
|
| (Var->hasReg() || Var->mustHaveReg())) {
|
| @@ -181,12 +221,6 @@ void LinearScan::initForInfOnly() {
|
| }
|
| }
|
| }
|
| - FOREACH_VAR_IN_INST(Var, Inst) {
|
| - if (Var->getIgnoreLiveness())
|
| - continue;
|
| - if (Var->hasReg() || Var->mustHaveReg())
|
| - LREnd[Var->getIndex()] = Inst.getNumber();
|
| - }
|
| }
|
| }
|
|
|
| @@ -195,7 +229,10 @@ void LinearScan::initForInfOnly() {
|
| for (SizeT i = 0; i < Vars.size(); ++i) {
|
| Variable *Var = Vars[i];
|
| if (LRBegin[i] != Inst::NumberSentinel) {
|
| - assert(LREnd[i] != Inst::NumberSentinel);
|
| + if (LREnd[i] == Inst::NumberSentinel) {
|
| + DefsWithoutUses.push_back(i);
|
| + continue;
|
| + }
|
| Unhandled.push_back(Var);
|
| Var->resetLiveRange();
|
| Var->addLiveRange(LRBegin[i], LREnd[i]);
|
| @@ -208,6 +245,30 @@ void LinearScan::initForInfOnly() {
|
| --NumVars;
|
| }
|
| }
|
| +
|
| + if (!livenessValidateIntervals(DefsWithoutUses, UsesBeforeDefs, LRBegin,
|
| + LREnd)) {
|
| + llvm::report_fatal_error("initForInfOnly: Liveness error");
|
| + return;
|
| + }
|
| +
|
| + if (!DefsWithoutUses.empty() || !UsesBeforeDefs.empty()) {
|
| + if (BuildDefs::dump()) {
|
| + OstreamLocker L(Ctx);
|
| + Ostream &Str = Ctx->getStrDump();
|
| + for (SizeT VarNum : DefsWithoutUses) {
|
| + Variable *Var = Vars[VarNum];
|
| + Str << "LR def without use, instruction " << LRBegin[VarNum]
|
| + << ", variable " << Var->getName(Func) << "\n";
|
| + }
|
| + for (SizeT VarNum : UsesBeforeDefs) {
|
| + Variable *Var = Vars[VarNum];
|
| + Str << "LR use before def, instruction " << LREnd[VarNum]
|
| + << ", variable " << Var->getName(Func) << "\n";
|
| + }
|
| + }
|
| + llvm::report_fatal_error("initForInfOnly: Liveness error");
|
| + }
|
| // This isn't actually a fatal condition, but it would be nice to know if we
|
| // somehow pre-calculated Unhandled's size wrong.
|
| assert(NumVars == 0);
|
|
|