summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/RegAllocBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/RegAllocBase.cpp')
-rw-r--r--llvm/lib/CodeGen/RegAllocBase.cpp61
1 files changed, 48 insertions, 13 deletions
diff --git a/llvm/lib/CodeGen/RegAllocBase.cpp b/llvm/lib/CodeGen/RegAllocBase.cpp
index 449033d63210..50addcbcca06 100644
--- a/llvm/lib/CodeGen/RegAllocBase.cpp
+++ b/llvm/lib/CodeGen/RegAllocBase.cpp
@@ -23,6 +23,7 @@
#include "llvm/CodeGen/Spiller.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/VirtRegMap.h"
+#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
@@ -123,21 +124,10 @@ void RegAllocBase::allocatePhysRegs() {
}
const TargetRegisterClass *RC = MRI->getRegClass(VirtReg->reg());
- ArrayRef<MCPhysReg> AllocOrder = RegClassInfo.getOrder(RC);
- if (AllocOrder.empty())
- report_fatal_error("no registers from class available to allocate");
- else if (MI && MI->isInlineAsm()) {
- MI->emitError("inline assembly requires more registers than available");
- } else if (MI) {
- LLVMContext &Context =
- MI->getParent()->getParent()->getFunction().getContext();
- Context.emitError("ran out of registers during register allocation");
- } else {
- report_fatal_error("ran out of registers during register allocation");
- }
+ AvailablePhysReg = getErrorAssignment(*RC, MI);
// Keep going after reporting the error.
- VRM->assignVirt2Phys(VirtReg->reg(), AllocOrder.front());
+ VRM->assignVirt2Phys(VirtReg->reg(), AvailablePhysReg);
} else if (AvailablePhysReg)
Matrix->assign(*VirtReg, AvailablePhysReg);
@@ -187,3 +177,48 @@ void RegAllocBase::enqueue(const LiveInterval *LI) {
<< " in skipped register class\n");
}
}
+
+MCPhysReg RegAllocBase::getErrorAssignment(const TargetRegisterClass &RC,
+ const MachineInstr *CtxMI) {
+ MachineFunction &MF = VRM->getMachineFunction();
+
+ // Avoid printing the error for every single instance of the register. It
+ // would be better if this were per register class.
+ bool EmitError = !MF.getProperties().hasProperty(
+ MachineFunctionProperties::Property::FailedRegAlloc);
+ if (EmitError)
+ MF.getProperties().set(MachineFunctionProperties::Property::FailedRegAlloc);
+
+ const Function &Fn = MF.getFunction();
+ LLVMContext &Context = Fn.getContext();
+
+ ArrayRef<MCPhysReg> AllocOrder = RegClassInfo.getOrder(&RC);
+ if (AllocOrder.empty()) {
+ // If the allocation order is empty, it likely means all registers in the
+ // class are reserved. We still to need to pick something, so look at the
+ // underlying class.
+ ArrayRef<MCPhysReg> RawRegs = RC.getRegisters();
+
+ if (EmitError) {
+ Context.diagnose(DiagnosticInfoRegAllocFailure(
+ "no registers from class available to allocate", Fn,
+ CtxMI ? CtxMI->getDebugLoc() : DiagnosticLocation()));
+ }
+
+ assert(!RawRegs.empty() && "register classes cannot have no registers");
+ return RawRegs.front();
+ }
+
+ if (EmitError) {
+ if (CtxMI && CtxMI->isInlineAsm()) {
+ CtxMI->emitInlineAsmError(
+ "inline assembly requires more registers than available");
+ } else {
+ Context.diagnose(DiagnosticInfoRegAllocFailure(
+ "ran out of registers during register allocation", Fn,
+ CtxMI ? CtxMI->getDebugLoc() : DiagnosticLocation()));
+ }
+ }
+
+ return AllocOrder.front();
+}