summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2015-07-09 22:09:41 +0000
committerReid Kleckner <reid@kleckner.net>2015-07-09 22:09:41 +0000
commit8eecb3c160ac1c51c8401daaa394d2f5bf9a2871 (patch)
treed2baf2dd8603267d16fae54b7d5b464e9d50979b /llvm/lib
parentc16b1078dfb29a2216b651b6b24cc3626ba4dfb3 (diff)
downloadbcm5719-llvm-8eecb3c160ac1c51c8401daaa394d2f5bf9a2871.tar.gz
bcm5719-llvm-8eecb3c160ac1c51c8401daaa394d2f5bf9a2871.zip
[WinEH] Give up on using CSRs across 32-bit invokes for now
The runtime does not restore CSRs when transferring control back to the function handling the exception. According to the experts on IRC, LLVM's register allocator has no way to model register clobbers that only happen on one edge of the CFG. For now, don't worry about trying to use the meager three CSRs available on 32-bit X86 and just say that such invokes preserve nothing. llvm-svn: 241865
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp19
1 files changed, 17 insertions, 2 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 74e5dd62ccb..2e689fbe3d9 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -3258,9 +3258,24 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
RegsToPass[i].second.getValueType()));
// Add a register mask operand representing the call-preserved registers.
- const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo();
- const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
+ const uint32_t *Mask = RegInfo->getCallPreservedMask(MF, CallConv);
assert(Mask && "Missing call preserved mask for calling convention");
+
+ // If this is an invoke in a 32-bit function using an MSVC personality, assume
+ // the function clobbers all registers. If an exception is thrown, the runtime
+ // will not restore CSRs.
+ // FIXME: Model this more precisely so that we can register allocate across
+ // the normal edge and spill and fill across the exceptional edge.
+ if (!Is64Bit && CLI.CS && CLI.CS->isInvoke()) {
+ const Function *CallerFn = MF.getFunction();
+ EHPersonality Pers =
+ CallerFn->hasPersonalityFn()
+ ? classifyEHPersonality(CallerFn->getPersonalityFn())
+ : EHPersonality::Unknown;
+ if (isMSVCEHPersonality(Pers))
+ Mask = RegInfo->getNoPreservedMask();
+ }
+
Ops.push_back(DAG.getRegisterMask(Mask));
if (InFlag.getNode())
OpenPOWER on IntegriCloud