diff options
-rw-r--r-- | include/llvm/CodeGen/MachineInstr.h | 10 | ||||
-rw-r--r-- | lib/CodeGen/MachineInstr.cpp | 24 | ||||
-rw-r--r-- | lib/Target/X86/X86FloatingPoint.cpp | 22 |
3 files changed, 46 insertions, 10 deletions
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 788d149c86..5b3d3ea62a 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -22,6 +22,7 @@ #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/Support/DebugLoc.h" #include <vector> @@ -180,6 +181,15 @@ public: /// DebugLoc getDebugLoc() const { return debugLoc; } + /// emitError - Emit an error referring to the source location of this + /// instruction. This should only be used for inline assembly that is somehow + /// impossible to compile. Other errors should have been handled much + /// earlier. + /// + /// If this method returns, the caller should try to recover from the error. + /// + void emitError(StringRef Msg) const; + /// getDesc - Returns the target instruction descriptor of this /// MachineInstr. const MCInstrDesc &getDesc() const { return *MCID; } diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 77828c929e..f490713e72 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -15,13 +15,16 @@ #include "llvm/Constants.h" #include "llvm/Function.h" #include "llvm/InlineAsm.h" +#include "llvm/LLVMContext.h" #include "llvm/Metadata.h" +#include "llvm/Module.h" #include "llvm/Type.h" #include "llvm/Value.h" #include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineMemOperand.h" +#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/MC/MCInstrDesc.h" @@ -1712,3 +1715,24 @@ MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) { } return Hash; } + +void MachineInstr::emitError(StringRef Msg) const { + // Find the source location cookie. + unsigned LocCookie = 0; + const MDNode *LocMD = 0; + for (unsigned i = getNumOperands(); i != 0; --i) { + if (getOperand(i-1).isMetadata() && + (LocMD = getOperand(i-1).getMetadata()) && + LocMD->getNumOperands() != 0) { + if (const ConstantInt *CI = dyn_cast<ConstantInt>(LocMD->getOperand(0))) { + LocCookie = CI->getZExtValue(); + break; + } + } + } + + if (const MachineBasicBlock *MBB = getParent()) + if (const MachineFunction *MF = MBB->getParent()) + return MF->getMMI().getModule()->getContext().emitError(LocCookie, Msg); + report_fatal_error(Msg); +} diff --git a/lib/Target/X86/X86FloatingPoint.cpp b/lib/Target/X86/X86FloatingPoint.cpp index 463cde076a..04e01ddf8f 100644 --- a/lib/Target/X86/X86FloatingPoint.cpp +++ b/lib/Target/X86/X86FloatingPoint.cpp @@ -884,7 +884,7 @@ void FPS::adjustLiveRegs(unsigned Mask, MachineBasicBlock::iterator I) { // Kill registers by popping. if (Kills && I != MBB->begin()) { MachineBasicBlock::iterator I2 = llvm::prior(I); - for (;;) { + while (StackTop) { unsigned KReg = getStackEntry(0); if (!(Kills & (1 << KReg))) break; @@ -1467,25 +1467,27 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) { } if (STUses && !isMask_32(STUses)) - report_fatal_error("Inline asm fixed input regs" - " must be last on the x87 stack"); + MI->emitError("Inline asm fixed input regs" + " must be last on the x87 stack"); unsigned NumSTUses = CountTrailingOnes_32(STUses); // Defs must be contiguous from the stack top. ST0-STn. - if (STDefs && !isMask_32(STDefs)) - report_fatal_error("Inline asm output regs" - " must be last on the x87 stack"); + if (STDefs && !isMask_32(STDefs)) { + MI->emitError("Inline asm output regs" + " must be last on the x87 stack"); + STDefs = NextPowerOf2(STDefs) - 1; + } unsigned NumSTDefs = CountTrailingOnes_32(STDefs); // So must the clobbered stack slots. ST0-STm, m >= n. if (STClobbers && !isMask_32(STDefs | STClobbers)) - report_fatal_error("Inline asm clobbers must be last on the x87 stack"); + MI->emitError("Inline asm clobbers must be last on the x87 stack"); // Popped inputs are the ones that are also clobbered or defined. unsigned STPopped = STUses & (STDefs | STClobbers); if (STPopped && !isMask_32(STPopped)) - report_fatal_error("Inline asm implicitly popped regs" - " must be last on the x87 stack"); + MI->emitError("Inline asm implicitly popped regs" + " must be last on the x87 stack"); unsigned NumSTPopped = CountTrailingOnes_32(STPopped); DEBUG(dbgs() << "Asm uses " << NumSTUses << " fixed regs, pops " @@ -1501,7 +1503,7 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) { if (!Op.isReg() || Op.getReg() < X86::FP0 || Op.getReg() > X86::FP6) continue; if (!Op.isUse()) - report_fatal_error("Illegal \"f\" output constraint in inline asm"); + MI->emitError("Illegal \"f\" output constraint in inline asm"); unsigned FPReg = getFPReg(Op); FPUsed |= 1U << FPReg; |