[llvm-commits] [llvm-gcc-4.2] r48365 - in /llvm-gcc-4.2/trunk/gcc: except.c llvm-convert.cpp llvm-internal.h
Duncan Sands
baldrick at free.fr
Fri Mar 14 10:51:45 PDT 2008
Author: baldrick
Date: Fri Mar 14 12:51:45 2008
New Revision: 48365
URL: http://llvm.org/viewvc/llvm-project?rev=48365&view=rev
Log:
Enforce must-not-throw regions using invoke+terminate
("terminate" depends on the language) rather than by
using the 'nounwind' attribute. This conceptually
simplifies the meaning of 'nounwind' at a small cost
in code size, which could in theory be eliminated by
an appropriate codegen pass. The key change is in
except.c.
Modified:
llvm-gcc-4.2/trunk/gcc/except.c
llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
llvm-gcc-4.2/trunk/gcc/llvm-internal.h
Modified: llvm-gcc-4.2/trunk/gcc/except.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/except.c?rev=48365&r1=48364&r2=48365&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/except.c (original)
+++ llvm-gcc-4.2/trunk/gcc/except.c Fri Mar 14 12:51:45 2008
@@ -2650,13 +2650,21 @@
inline a subroutine that contains handlers, and that will
change the value of saw_any_handlers. */
+/* LLVM local begin */
+#ifndef ENABLE_LLVM
if ((info && info->saw_any_handlers) || !cfun->after_inlining)
{
+#endif
+/* LLVM local end */
add_reachable_handler (info, region, region);
return RNL_CAUGHT;
+/* LLVM local begin */
+#ifndef ENABLE_LLVM
}
else
return RNL_BLOCKED;
+#endif
+/* LLVM local end */
case ERT_THROW:
case ERT_UNKNOWN:
Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=48365&r1=48364&r2=48365&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Fri Mar 14 12:51:45 2008
@@ -66,7 +66,6 @@
#include "rtl.h"
#include "libfuncs.h"
#include "tree-flow.h"
-extern bool tree_could_throw_p(tree); // tree-flow.h uses non-C++ C constructs.
extern int get_pointer_alignment (tree exp, unsigned int max_align);
extern enum machine_mode reg_raw_mode[FIRST_PSEUDO_REGISTER];
}
@@ -350,7 +349,7 @@
TreeToLLVM::TreeToLLVM(tree fndecl) : TD(getTargetData()) {
FnDecl = fndecl;
Fn = 0;
- ReturnBB = UnwindBB = NoUnwindBB = 0;
+ ReturnBB = UnwindBB = 0;
if (TheDebugInfo) {
expanded_location Location = expand_location(DECL_SOURCE_LOCATION (fndecl));
@@ -769,7 +768,6 @@
EmitLandingPads();
EmitPostPads();
EmitUnwindBlock();
- EmitNoUnwindBlock();
// If this function takes the address of a label, emit the indirect goto
// block.
@@ -2081,16 +2079,13 @@
if (TargetBB) {
Builder.CreateBr(TargetBB);
- } else if (can_throw_external_1(i, true)) {
+ } else {
+ assert(can_throw_external_1(i, true) &&
+ "Must-not-throw region handled by runtime?");
// Unwinding continues in the caller.
if (!UnwindBB)
UnwindBB = new BasicBlock("Unwind");
Builder.CreateBr(UnwindBB);
- } else {
- // Unwinding in a must_not_throw region - notify the runtime.
- if (!NoUnwindBB)
- NoUnwindBB = new BasicBlock("NoUnwind");
- Builder.CreateBr(NoUnwindBB);
}
Handlers.clear();
@@ -2110,22 +2105,6 @@
}
}
-/// EmitNoUnwindBlock - Emit the lazily created EH illegal-unwind block.
-void TreeToLLVM::EmitNoUnwindBlock() {
- if (NoUnwindBB) {
- CreateExceptionValues();
- EmitBlock(NoUnwindBB);
- // Fetch and store exception handler.
- Value *Arg = Builder.CreateLoad(ExceptionValue, "eh_ptr");
- assert(llvm_unwind_resume_libfunc && "no unwind resume function!");
- CallInst *Call =
- Builder.CreateCall(DECL_LLVM(llvm_unwind_resume_libfunc), Arg);
- // Illegal unwind - notify the runtime.
- Call->setDoesNotThrow();
- Builder.CreateUnreachable();
- }
-}
-
//===----------------------------------------------------------------------===//
// ... Expressions ...
//===----------------------------------------------------------------------===//
@@ -2447,26 +2426,26 @@
/// result, otherwise store it in DestLoc.
Value *TreeToLLVM::EmitCallOf(Value *Callee, tree exp, const MemRef *DestLoc,
const PAListPtr &InPAL) {
+ BasicBlock *LandingPad = 0; // Non-zero indicates an invoke.
+
PAListPtr PAL = InPAL;
if (PAL.isEmpty() && isa<Function>(Callee))
PAL = cast<Function>(Callee)->getParamAttrs();
- // Determine if we need to generate an invoke instruction (instead of a simple
- // call) and if so, what the exception destination will be.
- BasicBlock *LandingPad = 0;
- bool NoUnwind =
- (PAL.paramHasAttr(0, ParamAttr::NoUnwind)) ||
- !tree_could_throw_p(exp);
+ if (!tree_could_throw_p(exp))
+ // This call does not throw - mark it 'nounwind'.
+ PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
- // Do not turn nounwind calls into invokes.
- if (!NoUnwind) {
+ if (!PAL.paramHasAttr(0, ParamAttr::NoUnwind)) {
+ // This call may throw. Determine if we need to generate
+ // an invoke rather than a simple call.
int RegionNo = lookup_stmt_eh_region(exp);
// Is the call contained in an exception handling region?
if (RegionNo > 0) {
// Are there any exception handlers for this region?
if (can_throw_internal_1(RegionNo, false)) {
- // Turn the call into an invoke.
+ // There are - turn the call into an invoke.
LandingPads.grow(RegionNo);
BasicBlock *&ThisPad = LandingPads[RegionNo];
@@ -2476,17 +2455,12 @@
LandingPad = ThisPad;
} else {
- // Can this call unwind out of the current function?
- NoUnwind = !can_throw_external_1(RegionNo, false);
+ assert(can_throw_external_1(RegionNo, false) &&
+ "Must-not-throw region handled by runtime?");
}
}
}
- if (NoUnwind)
- // This particular call does not unwind even though the callee may
- // unwind in general. Add the 'nounwind' attribute to the call.
- PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
-
SmallVector<Value*, 16> CallOperands;
CallingConv::ID CallingConvention;
FunctionCallArgumentConversion Client(exp, CallOperands, CallingConvention,
@@ -3455,16 +3429,13 @@
getPostPad(get_eh_region_number(*I));
Builder.CreateBr(getPostPad(get_eh_region_number(*Handlers.begin())));
- } else if (can_throw_external_1(RegionNo, true)) {
+ } else {
+ assert(can_throw_external_1(RegionNo, true) &&
+ "Must-not-throw region handled by runtime?");
// Unwinding continues in the caller.
if (!UnwindBB)
UnwindBB = new BasicBlock("Unwind");
Builder.CreateBr(UnwindBB);
- } else {
- // Unwinding in a must_not_throw region - notify the runtime.
- if (!NoUnwindBB)
- NoUnwindBB = new BasicBlock("NoUnwind");
- Builder.CreateBr(NoUnwindBB);
}
EmitBlock(new BasicBlock(""));
Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=48365&r1=48364&r2=48365&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Fri Mar 14 12:51:45 2008
@@ -274,7 +274,6 @@
Function *Fn;
BasicBlock *ReturnBB;
BasicBlock *UnwindBB;
- BasicBlock *NoUnwindBB;
// State that changes as the function is emitted.
@@ -432,9 +431,6 @@
/// EmitUnwindBlock - Emit the lazily created EH unwind block.
void EmitUnwindBlock();
- /// EmitNoUnwindBlock - Emit the lazily created EH illegal-unwind block.
- void EmitNoUnwindBlock();
-
private: // Helpers for exception handling.
/// CreateExceptionValues - Create values used internally by exception
More information about the llvm-commits
mailing list