From: Nicolai Haehnle Date: Wed, 15 May 2019 17:29:58 +0000 (+0000) Subject: RegAlloc: try to fail more gracefully when out of registers X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ffd67742342c909eaeb9131dd63fffcfce265543;p=llvm RegAlloc: try to fail more gracefully when out of registers Summary: The emitError path allows the program to continue, unlike report_fatal_error. This is friendlier to use cases where LLVM is embedded in a larger program, because the caller may be able to deal with the error somewhat gracefully. Change the number of requested NOP bytes in the AArch64 and PowerPC test cases to avoid triggering an unrelated assertion. The compilation still fails, as verified by the test. Change-Id: Iafb9ca341002a597b82e59ddc7a1f13c78758e3d Reviewers: arsenm, MatzeB Subscribers: qcolombet, nemanjai, wdng, javed.absar, kristof.beyls, kbarton, jsji, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D61489 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360786 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/RegAllocBase.cpp b/lib/CodeGen/RegAllocBase.cpp index 0df951dc997..1cbe75c27d1 100644 --- a/lib/CodeGen/RegAllocBase.cpp +++ b/lib/CodeGen/RegAllocBase.cpp @@ -19,6 +19,7 @@ #include "llvm/CodeGen/LiveIntervals.h" #include "llvm/CodeGen/LiveRegMatrix.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/VirtRegMap.h" @@ -118,16 +119,19 @@ void RegAllocBase::allocatePhysRegs() { for (MachineRegisterInfo::reg_instr_iterator I = MRI->reg_instr_begin(VirtReg->reg), E = MRI->reg_instr_end(); I != E; ) { - MachineInstr *TmpMI = &*(I++); - if (TmpMI->isInlineAsm()) { - MI = TmpMI; + MI = &*(I++); + if (MI->isInlineAsm()) break; - } } - if (MI) + if (MI && MI->isInlineAsm()) { MI->emitError("inline assembly requires more registers than available"); - else + } else if (MI) { + LLVMContext &Context = + MI->getParent()->getParent()->getMMI().getModule()->getContext(); + Context.emitError("ran out of registers during register allocation"); + } else { report_fatal_error("ran out of registers during register allocation"); + } // Keep going after reporting the error. VRM->assignVirt2Phys(VirtReg->reg, RegClassInfo.getOrder(MRI->getRegClass(VirtReg->reg)).front()); diff --git a/test/CodeGen/AArch64/arm64-anyregcc-crash.ll b/test/CodeGen/AArch64/arm64-anyregcc-crash.ll index 56c62d5fe7d..f8852262a65 100644 --- a/test/CodeGen/AArch64/arm64-anyregcc-crash.ll +++ b/test/CodeGen/AArch64/arm64-anyregcc-crash.ll @@ -2,13 +2,13 @@ ; ; Check that misuse of anyregcc results in a compile time error. -; CHECK: LLVM ERROR: ran out of registers during register allocation +; CHECK: error: ran out of registers during register allocation define i64 @anyreglimit(i64 %v1, i64 %v2, i64 %v3, i64 %v4, i64 %v5, i64 %v6, i64 %v7, i64 %v8, i64 %v9, i64 %v10, i64 %v11, i64 %v12, i64 %v13, i64 %v14, i64 %v15, i64 %v16, i64 %v17, i64 %v18, i64 %v19, i64 %v20, i64 %v21, i64 %v22, i64 %v23, i64 %v24, i64 %v25, i64 %v26, i64 %v27, i64 %v28, i64 %v29, i64 %v30, i64 %v31, i64 %v32) { entry: - %result = tail call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 12, i32 15, i8* inttoptr (i64 0 to i8*), i32 32, + %result = tail call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 12, i32 16, i8* inttoptr (i64 0 to i8*), i32 32, i64 %v1, i64 %v2, i64 %v3, i64 %v4, i64 %v5, i64 %v6, i64 %v7, i64 %v8, i64 %v9, i64 %v10, i64 %v11, i64 %v12, i64 %v13, i64 %v14, i64 %v15, i64 %v16, i64 %v17, i64 %v18, i64 %v19, i64 %v20, i64 %v21, i64 %v22, i64 %v23, i64 %v24, diff --git a/test/CodeGen/PowerPC/ppc64-anyregcc-crash.ll b/test/CodeGen/PowerPC/ppc64-anyregcc-crash.ll index e19ab11e43f..e1ffe913adb 100644 --- a/test/CodeGen/PowerPC/ppc64-anyregcc-crash.ll +++ b/test/CodeGen/PowerPC/ppc64-anyregcc-crash.ll @@ -2,13 +2,13 @@ ; ; Check that misuse of anyregcc results in a compile time error. -; CHECK: LLVM ERROR: ran out of registers during register allocation +; CHECK: error: ran out of registers during register allocation define i64 @anyreglimit(i64 %v1, i64 %v2, i64 %v3, i64 %v4, i64 %v5, i64 %v6, i64 %v7, i64 %v8, i64 %v9, i64 %v10, i64 %v11, i64 %v12, i64 %v13, i64 %v14, i64 %v15, i64 %v16, i64 %v17, i64 %v18, i64 %v19, i64 %v20, i64 %v21, i64 %v22, i64 %v23, i64 %v24, i64 %v25, i64 %v26, i64 %v27, i64 %v28, i64 %v29, i64 %v30, i64 %v31, i64 %v32) { entry: - %result = tail call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 12, i32 15, i8* inttoptr (i64 0 to i8*), i32 32, + %result = tail call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 12, i32 16, i8* inttoptr (i64 0 to i8*), i32 32, i64 %v1, i64 %v2, i64 %v3, i64 %v4, i64 %v5, i64 %v6, i64 %v7, i64 %v8, i64 %v9, i64 %v10, i64 %v11, i64 %v12, i64 %v13, i64 %v14, i64 %v15, i64 %v16, i64 %v17, i64 %v18, i64 %v19, i64 %v20, i64 %v21, i64 %v22, i64 %v23, i64 %v24, diff --git a/test/CodeGen/X86/anyregcc-crash.ll b/test/CodeGen/X86/anyregcc-crash.ll index a7c104e3ba4..9fac1c6f5bb 100644 --- a/test/CodeGen/X86/anyregcc-crash.ll +++ b/test/CodeGen/X86/anyregcc-crash.ll @@ -2,7 +2,7 @@ ; ; Check that misuse of anyregcc results in a compile time error. -; CHECK: LLVM ERROR: ran out of registers during register allocation +; CHECK: error: ran out of registers during register allocation define i64 @anyreglimit(i64 %v1, i64 %v2, i64 %v3, i64 %v4, i64 %v5, i64 %v6, i64 %v7, i64 %v8, i64 %v9, i64 %v10, i64 %v11, i64 %v12, i64 %v13, i64 %v14, i64 %v15, i64 %v16) {