summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/WinEHPrepare.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2015-06-09 21:42:19 +0000
committerReid Kleckner <reid@kleckner.net>2015-06-09 21:42:19 +0000
commitf12c030f4879e2bf2caca21976f5de9ba8c48bdd (patch)
tree21b2e4664e29273f3905ed81222e87a61abeec1c /llvm/lib/CodeGen/WinEHPrepare.cpp
parentcf90acc1041fea47db7d862a21b24534b5df21b0 (diff)
downloadbcm5719-llvm-f12c030f4879e2bf2caca21976f5de9ba8c48bdd.tar.gz
bcm5719-llvm-f12c030f4879e2bf2caca21976f5de9ba8c48bdd.zip
[WinEH] Add 32-bit SEH state table emission prototype
This gets all the handler info through to the asm printer and we can look at the .xdata tables now. I've convinced one small catch-all test case to work, but other than that, it would be a stretch to say this is functional. The state numbering algorithm avoids doing any scope reconstruction as we do for C++ to simplify the implementation. llvm-svn: 239433
Diffstat (limited to 'llvm/lib/CodeGen/WinEHPrepare.cpp')
-rw-r--r--llvm/lib/CodeGen/WinEHPrepare.cpp22
1 files changed, 17 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp
index c2b3d84ca36..6bdc9c95d61 100644
--- a/llvm/lib/CodeGen/WinEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WinEHPrepare.cpp
@@ -24,6 +24,7 @@
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Analysis/LibCallSemantics.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/CodeGen/WinEHFuncInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
@@ -124,6 +125,7 @@ private:
// All fields are reset by runOnFunction.
DominatorTree *DT = nullptr;
+ const TargetLibraryInfo *LibInfo = nullptr;
EHPersonality Personality = EHPersonality::Unknown;
CatchHandlerMapTy CatchHandlerMap;
CleanupHandlerMapTy CleanupHandlerMap;
@@ -384,6 +386,7 @@ bool WinEHPrepare::runOnFunction(Function &Fn) {
return false;
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ LibInfo = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
// If there were any landing pads, prepareExceptionHandlers will make changes.
prepareExceptionHandlers(Fn, LPads);
@@ -394,6 +397,7 @@ bool WinEHPrepare::doFinalization(Module &M) { return false; }
void WinEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<DominatorTreeWrapperPass>();
+ AU.addRequired<TargetLibraryInfoWrapperPass>();
}
static bool isSelectorDispatch(BasicBlock *BB, BasicBlock *&CatchHandler,
@@ -1016,10 +1020,17 @@ bool WinEHPrepare::prepareExceptionHandlers(
Builder.CreateCall(FrameEscapeFn, AllocasToEscape);
if (SEHExceptionCodeSlot) {
- if (SEHExceptionCodeSlot->hasNUses(0))
- SEHExceptionCodeSlot->eraseFromParent();
- else if (isAllocaPromotable(SEHExceptionCodeSlot))
+ if (isAllocaPromotable(SEHExceptionCodeSlot)) {
+ SmallPtrSet<BasicBlock *, 4> UserBlocks;
+ for (User *U : SEHExceptionCodeSlot->users()) {
+ if (auto *Inst = dyn_cast<Instruction>(U))
+ UserBlocks.insert(Inst->getParent());
+ }
PromoteMemToReg(SEHExceptionCodeSlot, *DT);
+ // After the promotion, kill off dead instructions.
+ for (BasicBlock *BB : UserBlocks)
+ SimplifyInstructionsInBlock(BB, LibInfo);
+ }
}
// Clean up the handler action maps we created for this function
@@ -1029,6 +1040,7 @@ bool WinEHPrepare::prepareExceptionHandlers(
CleanupHandlerMap.clear();
HandlerToParentFP.clear();
DT = nullptr;
+ LibInfo = nullptr;
SEHExceptionCodeSlot = nullptr;
EHBlocks.clear();
NormalBlocks.clear();
@@ -1143,7 +1155,6 @@ void WinEHPrepare::completeNestedLandingPad(Function *ParentFn,
++II;
// The instruction after the landing pad should now be a call to eh.actions.
const Instruction *Recover = II;
- assert(match(Recover, m_Intrinsic<Intrinsic::eh_actions>()));
const IntrinsicInst *EHActions = cast<IntrinsicInst>(Recover);
// Remap the return target in the nested handler.
@@ -2454,6 +2465,8 @@ void WinEHPrepare::findCleanupHandlers(LandingPadActions &Actions,
void llvm::parseEHActions(
const IntrinsicInst *II,
SmallVectorImpl<std::unique_ptr<ActionHandler>> &Actions) {
+ assert(II->getIntrinsicID() == Intrinsic::eh_actions &&
+ "attempted to parse non eh.actions intrinsic");
for (unsigned I = 0, E = II->getNumArgOperands(); I != E;) {
uint64_t ActionKind =
cast<ConstantInt>(II->getArgOperand(I))->getZExtValue();
@@ -2766,7 +2779,6 @@ void WinEHNumbering::calculateStateNumbers(const Function &F) {
auto *ActionsCall = dyn_cast<IntrinsicInst>(LPI->getNextNode());
if (!ActionsCall)
continue;
- assert(ActionsCall->getIntrinsicID() == Intrinsic::eh_actions);
parseEHActions(ActionsCall, ActionList);
if (ActionList.empty())
continue;
OpenPOWER on IntegriCloud