Skip to content

Commit

Permalink
[IROutliner] Adding support for swift errors in the IROutliner
Browse files Browse the repository at this point in the history
Since some values can be swift errors, we need to make sure that we
correctly propagate the parameter attributes.

Tests found at:
llvm/test/Transforms/IROutliner/outlining-swift-error.ll

Reviewers: jroelofs, paquette

Recommit of: 71867ed

Differential Revision: https://reviews.llvm.org/D87742
  • Loading branch information
AndrewLitteken committed Dec 30, 2020
1 parent eeb99c2 commit 30feb93
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 1 deletion.
26 changes: 25 additions & 1 deletion llvm/lib/Transforms/IPO/IROutliner.cpp
Expand Up @@ -81,6 +81,10 @@ struct OutlinableGroup {
/// Regions.
unsigned Cost = 0;

/// The argument that needs to be marked with the swifterr attribute. If not
/// needed, there is no value.
Optional<unsigned> SwiftErrorArgument;

/// For the \ref Regions, we look at every Value. If it is a constant,
/// we check whether it is the same in Region.
///
Expand Down Expand Up @@ -352,6 +356,11 @@ Function *IROutliner::createFunction(Module &M, OutlinableGroup &Group,
Group.OutlinedFunctionType, GlobalValue::InternalLinkage,
"outlined_ir_func_" + std::to_string(FunctionNameSuffix), M);

// Transfer the swifterr attribute to the correct function parameter.
if (Group.SwiftErrorArgument.hasValue())
Group.OutlinedFunction->addParamAttr(Group.SwiftErrorArgument.getValue(),
Attribute::SwiftError);

Group.OutlinedFunction->addFnAttr(Attribute::OptimizeForSize);
Group.OutlinedFunction->addFnAttr(Attribute::MinSize);

Expand Down Expand Up @@ -570,8 +579,17 @@ findExtractedInputToOverallInputMapping(OutlinableRegion &Region,
assert(InputOpt.hasValue() && "Global value number not found?");
Value *Input = InputOpt.getValue();

if (!Group.InputTypesSet)
if (!Group.InputTypesSet) {
Group.ArgumentTypes.push_back(Input->getType());
// If the input value has a swifterr attribute, make sure to mark the
// argument in the overall function.
if (Input->isSwiftError()) {
assert(
!Group.SwiftErrorArgument.hasValue() &&
"Argument already marked with swifterr for this OutlinableGroup!");
Group.SwiftErrorArgument = TypeIndex;
}
}

// Check if we have a constant. If we do add it to the overall argument
// number to Constant map for the region, and continue to the next input.
Expand Down Expand Up @@ -792,6 +810,12 @@ CallInst *replaceCalledFunction(Module &M, OutlinableRegion &Region) {
OldCall->eraseFromParent();
Region.Call = Call;

// Make sure that the argument in the new function has the SwiftError
// argument.
if (Group.SwiftErrorArgument.hasValue())
Call->addParamAttr(Group.SwiftErrorArgument.getValue(),
Attribute::SwiftError);

return Call;
}

Expand Down
47 changes: 47 additions & 0 deletions llvm/test/Transforms/IROutliner/outlining-swift-error.ll
@@ -0,0 +1,47 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -verify -iroutliner -ir-outlining-no-cost < %s | FileCheck %s

%swift.error = type opaque

define void @outlining_swifterror1(%swift.error** swifterror %err) {
; CHECK-LABEL: @outlining_swifterror1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[X:%.*]] = alloca i64, align 8
; CHECK-NEXT: call void @outlined_ir_func_0(i64 5, i64* [[X]], %swift.error** swifterror [[ERR:%.*]])
; CHECK-NEXT: ret void
;
entry:
%x = alloca i64
%0 = mul i64 5, 5
%1 = add i64 %0, %0
store i64 %1, i64* %x
%casted = bitcast i64* %x to %swift.error*
store %swift.error* %casted, %swift.error** %err
ret void
}

define void @outlining_swifterror2(%swift.error** swifterror %err) {
; CHECK-LABEL: @outlining_swifterror2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[X:%.*]] = alloca i64, align 8
; CHECK-NEXT: call void @outlined_ir_func_0(i64 3, i64* [[X]], %swift.error** swifterror [[ERR:%.*]])
; CHECK-NEXT: ret void
;
entry:
%x = alloca i64
%0 = mul i64 3, 3
%1 = add i64 %0, %0
store i64 %1, i64* %x
%casted = bitcast i64* %x to %swift.error*
store %swift.error* %casted, %swift.error** %err
ret void
}

; CHECK: define internal void @outlined_ir_func_0(i64 [[ARG0:%.*]], i64* [[ARG1:%.*]], %swift.error** swifterror [[ARG2:%.*]])
; CHECK: entry_to_outline:
; CHECK-NEXT: [[TMP0:%.*]] = mul i64 [[ARG0]], [[ARG0]]
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[TMP0]], [[TMP0]]
; CHECK-NEXT: store i64 [[TMP1]], i64* [[ARG1]], align 4
; CHECK-NEXT: %casted = bitcast i64* [[ARG1]] to %swift.error*
; CHECK-NEXT: store %swift.error* %casted, %swift.error** [[ARG2]], align 8
; CHECK-NEXT: br label %entry_after_outline.exitStub

0 comments on commit 30feb93

Please sign in to comment.