diff options
-rw-r--r-- | llvm/lib/Transforms/Utils/CodeExtractor.cpp | 17 | ||||
-rw-r--r-- | llvm/test/Transforms/HotColdSplit/swifterror.ll | 43 |
2 files changed, 58 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp index 03e2b9db078..da227570179 100644 --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -961,11 +961,18 @@ CallInst *CodeExtractor::emitCallAndSwitchStatement(Function *newFunction, CallInst *call = nullptr; // Add inputs as params, or to be filled into the struct - for (Value *input : inputs) + unsigned ArgNo = 0; + SmallVector<unsigned, 1> SwiftErrorArgs; + for (Value *input : inputs) { if (AggregateArgs) StructValues.push_back(input); - else + else { params.push_back(input); + if (input->isSwiftError()) + SwiftErrorArgs.push_back(ArgNo); + } + ++ArgNo; + } // Create allocas for the outputs for (Value *output : outputs) { @@ -1021,6 +1028,12 @@ CallInst *CodeExtractor::emitCallAndSwitchStatement(Function *newFunction, } codeReplacer->getInstList().push_back(call); + // Set swifterror parameter attributes. + for (unsigned SwiftErrArgNo : SwiftErrorArgs) { + call->addParamAttr(SwiftErrArgNo, Attribute::SwiftError); + newFunction->addParamAttr(SwiftErrArgNo, Attribute::SwiftError); + } + Function::arg_iterator OutputArgBegin = newFunction->arg_begin(); unsigned FirstOut = inputs.size(); if (!AggregateArgs) diff --git a/llvm/test/Transforms/HotColdSplit/swifterror.ll b/llvm/test/Transforms/HotColdSplit/swifterror.ll new file mode 100644 index 00000000000..b97b0fa005e --- /dev/null +++ b/llvm/test/Transforms/HotColdSplit/swifterror.ll @@ -0,0 +1,43 @@ +; RUN: opt -hotcoldsplit -hotcoldsplit-threshold=0 -S < %s | FileCheck %s + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.14.0" + +%swift_error = type {i64, i8} + +declare void @sink() cold + +; CHECK-LABEL: define {{.*}}@in_arg( +; CHECK: call void @in_arg.cold.1(%swift_error** swifterror +define void @in_arg(%swift_error** swifterror %error_ptr_ref) { + br i1 undef, label %cold, label %exit + +cold: + store %swift_error* undef, %swift_error** %error_ptr_ref + call void @sink() + br label %exit + +exit: + ret void +} + +; CHECK-LABEL: define {{.*}}@in_alloca( +; CHECK: call void @in_alloca.cold.1(%swift_error** swifterror +define void @in_alloca() { + %err = alloca swifterror %swift_error* + br i1 undef, label %cold, label %exit + +cold: + store %swift_error* undef, %swift_error** %err + call void @sink() + br label %exit + +exit: + ret void +} + +; CHECK-LABEL: define {{.*}}@in_arg.cold.1({{.*}} swifterror +; CHECK: call {{.*}}@sink + +; CHECK-LABEL: define {{.*}}@in_alloca.cold.1({{.*}} swifterror +; CHECK: call {{.*}}@sink |