summaryrefslogtreecommitdiff
path: root/lib/Transforms/Coroutines
AgeCommit message (Collapse)Author
2017-12-30Use phi ranges to simplify code. No functionality change intended.Benjamin Kramer
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321585 91177308-0d34-0410-b5e6-96231b3b80d8
2017-10-31[coro] Make Spill a proper struct instead of deriving from pair.Benjamin Kramer
No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317027 91177308-0d34-0410-b5e6-96231b3b80d8
2017-10-15Reverting r315590; it did not include changes for llvm-tblgen, which is ↵Aaron Ballman
causing link errors for several people. Error LNK2019 unresolved external symbol "public: void __cdecl `anonymous namespace'::MatchableInfo::dump(void)const " (?dump@MatchableInfo@?A0xf4f1c304@@QEBAXXZ) referenced in function "public: void __cdecl `anonymous namespace'::AsmMatcherEmitter::run(class llvm::raw_ostream &)" (?run@AsmMatcherEmitter@?A0xf4f1c304@@QEAAXAEAVraw_ostream@llvm@@@Z) llvm-tblgen D:\llvm\2017\utils\TableGen\AsmMatcherEmitter.obj 1 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315854 91177308-0d34-0410-b5e6-96231b3b80d8
2017-10-12[dump] Remove NDEBUG from test to enable dump methods [NFC]Don Hinton
Summary: Add LLVM_FORCE_ENABLE_DUMP cmake option, and use it along with LLVM_ENABLE_ASSERTIONS to set LLVM_ENABLE_DUMP. Remove NDEBUG and only use LLVM_ENABLE_DUMP to enable dump methods. Move definition of LLVM_ENABLE_DUMP from config.h to llvm-config.h so it'll be picked up by public headers. Differential Revision: https://reviews.llvm.org/D38406 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315590 91177308-0d34-0410-b5e6-96231b3b80d8
2017-08-31[Analysis] Fix some Clang-tidy modernize-use-using and Include What You Use ↵Eugene Zelenko
warnings; other minor fixes. Also affected in files (NFC). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312289 91177308-0d34-0410-b5e6-96231b3b80d8
2017-08-25[coroutines] Add support for symmetric control transfer (musttail on ↵Gor Nishanov
coro.resumes followed by a suspend) Summary: Add musttail to any resume instructions that is immediately followed by a suspend (i.e. ret). We do this even in -O0 to support guaranteed tail call for symmetrical coroutine control transfer (C++ Coroutines TS extension). This transformation is done only in the resume part of the coroutine that has identical signature and calling convention as the coro.resume call. Reviewers: GorNishanov Reviewed By: GorNishanov Subscribers: EricWF, majnemer, llvm-commits Differential Revision: https://reviews.llvm.org/D37125 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311751 91177308-0d34-0410-b5e6-96231b3b80d8
2017-08-23[coroutines] CoroBegin from inner coroutines should be considered for spillsGor Nishanov
Summary: If a coroutine outer calls another coroutine inner and the inner coroutine body is inlined into the outer, coro.begin from the inner coroutine should be considered for spilling if accessed across suspends. Prior to this change, coroutine frame building code was not considering any coro.begins for spilling. With this change, we only ignore coro.begin for the current coroutine, but, any coro.begins that were inlined into the current coroutine are eligible for spills. Fixes PR34267 Reviewers: GorNishanov Subscribers: qcolombet, llvm-commits, EricWF Differential Revision: https://reviews.llvm.org/D37062 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311556 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-29Remove `inline` keyword from inline `classof` methodsSam Clegg
The style guide states that the explicit `inline` should not be used with inline methods. classof is very common inline method with a fair amount on inconsistency: $ git grep classof ./include | grep inline | wc -l 230 $ git grep classof ./include | grep -v inline | wc -l 257 I chose to target this method rather the larger change since this method is easily cargo-culted (I did it at least once). I considered doing the larger change and removing all occurrences but that would be a much larger change. Differential Revision: https://reviews.llvm.org/D33906 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306731 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-06Sort the remaining #include lines in include/... and lib/....Chandler Carruth
I did this a long time ago with a janky python script, but now clang-format has built-in support for this. I fed clang-format every line with a #include and let it re-sort things according to the precise LLVM rules for include ordering baked into clang-format these days. I've reverted a number of files where the results of sorting includes isn't healthy. Either places where we have legacy code relying on particular include ordering (where possible, I'll fix these separately) or where we have particular formatting around #include lines that I didn't want to disturb in this patch. This patch is *entirely* mechanical. If you get merge conflicts or anything, just ignore the changes in this patch and run clang-format over your #include lines in the files. Sorry for any noise here, but it is important to keep these things stable. I was seeing an increasing number of patches with irrelevant re-ordering of #include lines because clang-format was used. This patch at least isolates that churn, makes it easy to skip when resolving conflicts, and gets us to a clean baseline (again). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304787 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-02[coroutines] PR33271: Remove stray coro.save intrinsics during CoroSplitGor Nishanov
Summary: Optimization passes may remove llvm.coro.suspend intrinsic while leaving matching llvm.coro.save intrinsic orphaned. Make sure we clean up orphaned coro.saves. The bug manifested with a crash similar to this: ``` llvm_unreachable("Unknown type!"); llvm::MVT::getVT (Ty=0x489518, HandleUnknown=false) llvm::EVT::getEVT llvm::TargetLoweringBase::getValueType llvm::ComputeValueVTs llvm::SelectionDAGBuilder::visitTargetIntrinsic ``` Reviewers: GorNishanov Subscribers: EricWF, llvm-commits Differential Revision: https://reviews.llvm.org/D33817 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304518 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-01Reapply "[Cloning] Take another pass at properly cloning debug info"Keno Fischer
This was rL304226, reverted in 304228 due to a clang assertion failure on the build bots. That problem should have been addressed by clang commit rL304470. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304488 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-31[coroutines] Call initializePass in coroutine pass constructorsGor Nishanov
Summary: Fixes: https://bugs.llvm.org/show_bug.cgi?id=33226 Reviewers: chandlerc, davide, majnemer, dblaikie Reviewed By: chandlerc Subscribers: EricWF, llvm-commits Differential Revision: https://reviews.llvm.org/D33701 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304277 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-30Revert "[Cloning] Take another pass at properly cloning debug info"Keno Fischer
At least one build bot is complaining. Will investigate after lunch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304228 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-30[Cloning] Take another pass at properly cloning debug infoKeno Fischer
Summary: In rL302576, DISubprograms gained the constraint that a !dbg attachments to functions must have a 1:1 mapping to DISubprograms. As part of that change, the function cloning support was adjusted to attempt to enforce this invariant during cloning. However, there were several problems with the implementation. Part of these were fixed in rL304079. However, there was a more fundamental problem with these changes, namely that it bypasses the matadata value map, causing the cloned metadata to be a mix of metadata pointing to the new suprogram (where manual code was added to fix those up) and the old suprogram (where this was not the case). This mismatch could cause a number of different assertion failures in the DWARF emitter. Some of these are given at https://github.com/JuliaLang/julia/issues/22069, but some others have been observed as well. Attempt to rectify this by partially reverting the manual DI metadata fixup, and instead using the standard value map approach. To retain the desired semantics of not duplicating the compilation unit and inlined subprograms, explicitly freeze these in the value map. Reviewers: dblaikie, aprantl, GorNishanov, echristo Reviewed By: aprantl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D33655 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304226 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-27Cloning: Fix debug info cloningGor Nishanov
Summary: I believe https://reviews.llvm.org/rL302576 introduced two bugs: 1) it produces duplicate distinct variables for every: dbg.value describing the same variable. To fix the problme I switched form getDistinct() to get() in DebugLoc.cpp: auto reparentVar = [&](DILocalVariable *Var) { return DILocalVariable::getDistinct( 2) It passes NewFunction plain name as a linkagename parameter to Subprogram constructor. Breaks assert in: || DeclLinkageName.empty()) || LinkageName == DeclLinkageName) && "decl has a linkage name and it is different"' failed. #9 0x00007f5010261b75 llvm::DwarfUnit::applySubprogramDefinitionAttributes(llvm::DISubprogram const*, llvm::DIE&) /home/gor/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp:1173:3 # (Edit: reproducer added) Here how https://reviews.llvm.org/rL302576 broke coroutine debug info. Coroutine body of the original function is split into several parts by cloning and removing unneeded code. All parts describe the original function and variables present in the original function. For a simple case, prior to Split, original function has these two blocks: ``` PostSpill: ; preds = %AllocaSpillBB call void @llvm.dbg.value(metadata i32 %x, i64 0, metadata !14, metadata !15), !dbg !13 store i32 %x, i32* %x.addr, align 4 ... and sw.epilog: ; preds = %sw.bb %x.addr.reload.addr = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i32 0, i32 4, !dbg !20 %4 = load i32, i32* %x.addr.reload.addr, align 4, !dbg !20 call void @llvm.dbg.value(metadata i32 %4, i64 0, metadata !14, metadata !15), !dbg !13 !14 = !DILocalVariable(name: "x", arg: 1, scope: !6, file: !7, line: 55, type: !11) ``` Note that in two blocks different expression represent the same original user variable X. Before rL302576, for every cloned function there was exactly one cloned DILocalVariable(name: "x" as in: ``` define i8* @f(i32 %x) #0 !dbg !6 { ... !6 = distinct !DISubprogram(name: "f", scope: !7, file: !7, line: 55, type: !8, isLocal: false, isDefinition: true, scopeLine: 55, flags: DIFlagPrototyped, ... !14 = !DILocalVariable(name: "x", arg: 1, scope: !6, file: !7, line: 55, type: !11) define internal fastcc void @f.resume(%f.Frame* %FramePtr) #0 !dbg !25 { ... !25 = distinct !DISubprogram(name: "f", scope: !7, file: !7, line: 55, type: !8, isLocal: false, isDefinition: true, scopeLine: 55, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) !28 = !DILocalVariable(name: "x", arg: 1, scope: !25, file: !7, line: 55, type: !11) ``` After rL302576, for every cloned function there were as many DILocalVariable(name: "x" as there were "call void @llvm.dbg.value" for that variable. This was causing asserts in VerifyDebugInfo and AssemblyPrinter. Example: ``` !27 = distinct !DISubprogram(name: "f", linkageName: "f.resume", scope: !7, file: !7, line: 55, type: !8, isLocal: false, isDefinition: true, scopeLine: 55, !29 = distinct !DILocalVariable(name: "x", arg: 1, scope: !27, file: !7, line: 55, type: !11) !39 = distinct !DILocalVariable(name: "x", arg: 1, scope: !27, file: !7, line: 55, type: !11) !41 = distinct !DILocalVariable(name: "x", arg: 1, scope: !27, file: !7, line: 55, type: !11) ``` Second problem: Prior to rL302576, all clones were described by DISubprogram referring to original function. ``` define i8* @f(i32 %x) #0 !dbg !6 { ... !6 = distinct !DISubprogram(name: "f", scope: !7, file: !7, line: 55, type: !8, isLocal: false, isDefinition: true, scopeLine: 55, flags: DIFlagPrototyped, define internal fastcc void @f.resume(%f.Frame* %FramePtr) #0 !dbg !25 { ... !25 = distinct !DISubprogram(name: "f", scope: !7, file: !7, line: 55, type: !8, isLocal: false, isDefinition: true, scopeLine: 55, flags: DIFlagPrototyped, ``` After rL302576, DISubprogram for clones is of two minds, plain name refers to the original name, linkageName refers to plain name of the clone. ``` !27 = distinct !DISubprogram(name: "f", linkageName: "f.resume", scope: !7, file: !7, line: 55, type: !8, isLocal: false, isDefinition: true, scopeLine: 55, ``` I think the assumption in AsmPrinter is that both name and linkageName should refer to the same entity. It asserts here when they are not: ``` || DeclLinkageName.empty()) || LinkageName == DeclLinkageName) && "decl has a linkage name and it is different"' failed. #9 0x00007f5010261b75 llvm::DwarfUnit::applySubprogramDefinitionAttributes(llvm::DISubprogram const*, llvm::DIE&) /home/gor/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp:1173:3 ``` After this fix, behavior (with respect to coroutines) reverts to exactly as it was before and therefore making them debuggable again, or even more importantly, compilable, with "-g" Reviewers: dblaikie, echristo, aprantl Reviewed By: dblaikie Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D33614 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304079 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-27[coroutines] Define getPassName() for coroutine passesGor Nishanov
Reviewers: GorNishanov Reviewed By: GorNishanov Subscribers: EricWF, llvm-commits Differential Revision: https://reviews.llvm.org/D33622 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304065 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-25[coroutines] CoroFrame.cpp conform to coding convention (s/repeat/Repeat) (NFC)Gor Nishanov
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303826 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-25[coroutines] Relocate instructions that maybe spilled after coro.beginGor Nishanov
Summary: Frontend generates store instructions after allocas, for example: ``` define i8* @f(i64 %this) "coroutine.presplit"="1" personality i32 0 { entry: %this.addr = alloca i64 store i64 %this, i64* %this.addr .. %hdl = call i8* @llvm.coro.begin(token %id, i8* %alloc) ``` Such instructions may require spilling into coro.frame, but, coro-frame address is only available after coro.begin and thus needs to be moved after coro.begin. The only instructions that should not be moved are the arguments of coro.begin and all of their operands. Reviewers: GorNishanov, majnemer Reviewed By: GorNishanov Subscribers: llvm-commits, EricWF Differential Revision: https://reviews.llvm.org/D33527 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303825 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-24[coroutines] Allow rematerialization upto 4 times. Remove incorrect assertGor Nishanov
Reviewers: majnemer Subscribers: EricWF, llvm-commits Differential Revision: https://reviews.llvm.org/D33524 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303819 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-17[coroutines] Handle spills before catchswitchGor Nishanov
If we need to spill the result of the PHI instruction, we insert the spill after all of the PHIs and EHPads, however, in a catchswitch block there is no room to insert the spill. Make room by splitting away catchswitch into a separate block. Before the fix: catch.dispatch: %val = phi i32 [ 1, %if.then ], [ 2, %if.else ] %switch = catchswitch within none [label %catch] unwind label %cleanuppad After: catch.dispatch: %val = phi i32 [ 1, %if.then ], [ 2, %if.else ] %tok = cleanuppad within none [] ; spill goes here cleanupret from %tok unwind label %catch.dispatch.switch catch.dispatch.switch: %switch = catchswitch within none [label %catch] unwind label %cleanuppad https://reviews.llvm.org/D31846 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303232 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-16[coroutines] Handle unwind edge splittingGor Nishanov
Summary: RewritePHIs algorithm used in building of CoroFrame inserts a placeholder ``` %placeholder = phi [%val] ``` on every edge leading to a block starting with PHI node with multiple incoming edges, so that if one of the incoming values was spilled and need to be reloaded, we have a place to insert a reload. We use SplitEdge helper function to split the incoming edge. SplitEdge function does not deal with unwind edges comping into a block with an EHPad. This patch adds an ehAwareSplitEdge function that can correctly split the unwind edge. For landing pads, we clone the landing pad into every edge block and replace the original landing pad with a PHI collection the values from all incoming landing pads. For WinEH pads, we keep the original EHPad in place and insert cleanuppad/cleapret in the edge blocks. Reviewers: majnemer, rnk Reviewed By: majnemer Subscribers: EricWF, llvm-commits Differential Revision: https://reviews.llvm.org/D31845 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303172 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-03[IR] Abstract away ArgNo+1 attribute indexing as much as possibleReid Kleckner
Summary: Do three things to help with that: - Add AttributeList::FirstArgIndex, which is an enumerator currently set to 1. It allows us to change the indexing scheme with fewer changes. - Add addParamAttr/removeParamAttr. This just shortens addAttribute call sites that would otherwise need to spell out FirstArgIndex. - Remove some attribute-specific getters and setters from Function that take attribute list indices. Most of these were only used from BuildLibCalls, and doesNotAlias was only used to test or set if the return value is malloc-like. I'm happy to split the patch, but I think they are probably easier to review when taken together. This patch should be NFC, but it sets the stage to change the indexing scheme to this, which is more convenient when indexing into an array: 0: func attrs 1: retattrs 2...: arg attrs Reviewers: chandlerc, pete, javed.absar Subscribers: david2050, llvm-commits Differential Revision: https://reviews.llvm.org/D32811 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302060 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-02Re-land r301697 "[IR] Make add/remove Attributes use AttrBuilder instead of ↵Reid Kleckner
AttributeList" This time, I fixed, built, and tested clang. This reverts r301712. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301981 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-28Revert r301697 "[IR] Make add/remove Attributes use AttrBuilder instead of ↵Hans Wennborg
AttributeList" This broke the Clang build. (Clang-side patch missing?) Original commit message: > [IR] Make add/remove Attributes use AttrBuilder instead of > AttributeList > > This change cleans up call sites and avoids creating temporary > AttributeList objects. > > NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301712 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-28[IR] Make add/remove Attributes use AttrBuilder instead of AttributeListReid Kleckner
This change cleans up call sites and avoids creating temporary AttributeList objects. NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301697 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-12[IR] Redesign the case iterator in SwitchInst to actually be an iteratorChandler Carruth
and to expose a handle to represent the actual case rather than having the iterator return a reference to itself. All of this allows the iterator to be used with common STL facilities, standard algorithms, etc. Doing this exposed some missing facilities in the iterator facade that I've fixed and required some work to the actual iterator to fully support the necessary API. Differential Revision: https://reviews.llvm.org/D31548 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300032 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-10Allow DataLayout to specify addrspace for allocas.Matt Arsenault
LLVM makes several assumptions about address space 0. However, alloca is presently constrained to always return this address space. There's no real way to avoid using alloca, so without this there is no way to opt out of these assumptions. The problematic assumptions include: - That the pointer size used for the stack is the same size as the code size pointer, which is also the maximum sized pointer. - That 0 is an invalid, non-dereferencable pointer value. These are problems for AMDGPU because alloca is used to implement the private address space, which uses a 32-bit index as the pointer value. Other pointers are 64-bit and behave more like LLVM's notion of generic address space. By changing the address space used for allocas, we can change our generic pointer type to be LLVM's generic pointer type which does have similar properties. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299888 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-08[coroutines] Make CoroSplit pass deterministicGor Nishanov
coro-split-after-phi.ll test was flaky due to non-determinism in the coroutine frame construction that was sorting the spill vector using a pointer to a def as a part of the key. The sorting was intended to make sure that spills for the same def are kept together, however, we populate the vector by processing defs in order, so the spill entires will end up together anyways. This change removes spill sorting and restores the determinism in the test. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299809 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-07[coroutines] Insert spills of PHI instructions correctlyGor Nishanov
Summary: Fix a bug where we were inserting a spill in between the PHIs in the beginning of the block. Consider this fragment: ``` begin: %phi1 = phi i32 [ 0, %entry ], [ 2, %alt ] %phi2 = phi i32 [ 1, %entry ], [ 3, %alt ] %sp1 = call i8 @llvm.coro.suspend(token none, i1 false) switch i8 %sp1, label %suspend [i8 0, label %resume i8 1, label %cleanup] resume: call i32 @print(i32 %phi1) ``` Unless we are spilling the argument or result of the invoke, we were always inserting the spill immediately following the instruction. The fix adds a check that if the spilled instruction is a PHI Node, select an appropriate insert point with `getFirstInsertionPt()` that skips all the PHI Nodes and EH pads. Reviewers: majnemer, rnk Reviewed By: rnk Subscribers: qcolombet, EricWF, llvm-commits Differential Revision: https://reviews.llvm.org/D31799 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299771 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-21Rename AttributeSet to AttributeListReid Kleckner
Summary: This class is a list of AttributeSetNodes corresponding the function prototype of a call or function declaration. This class used to be called ParamAttrListPtr, then AttrListPtr, then AttributeSet. It is typically accessed by parameter and return value index, so "AttributeList" seems like a more intuitive name. Rename AttributeSetImpl to AttributeListImpl to follow suit. It's useful to rename this class so that we can rename AttributeSetNode to AttributeSet later. AttributeSet is the set of attributes that apply to a single function, argument, or return value. Reviewers: sanjoy, javed.absar, chandlerc, pete Reviewed By: pete Subscribers: pete, jholewinski, arsenm, dschuff, mehdi_amini, jfb, nhaehnle, sbc100, void, llvm-commits Differential Revision: https://reviews.llvm.org/D31102 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298393 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-16Remove getArgumentList() in favor of arg_begin(), args(), etcReid Kleckner
Users often call getArgumentList().size(), which is a linear way to get the number of function arguments. arg_size(), on the other hand, is constant time. In general, the fact that arguments are stored in an iplist is an implementation detail, so I've removed it from the Function interface and moved all other users to the argument container APIs (arg_begin(), arg_end(), args(), arg_size()). Reviewed By: chandlerc Differential Revision: https://reviews.llvm.org/D31052 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298010 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-07[coroutines] Add handling for unwind coro.endsGor Nishanov
Summary: The purpose of coro.end intrinsic is to allow frontends to mark the cleanup and other code that is only relevant during the initial invocation of the coroutine and should not be present in resume and destroy parts. In landing pads coro.end is replaced with an appropriate instruction to unwind to caller. The handling of coro.end differs depending on whether the target is using landingpad or WinEH exception model. For landingpad based exception model, it is expected that frontend uses the `coro.end`_ intrinsic as follows: ``` ehcleanup: %InResumePart = call i1 @llvm.coro.end(i8* null, i1 true) br i1 %InResumePart, label %eh.resume, label %cleanup.cont cleanup.cont: ; rest of the cleanup eh.resume: %exn = load i8*, i8** %exn.slot, align 8 %sel = load i32, i32* %ehselector.slot, align 4 %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn, 0 %lpad.val29 = insertvalue { i8*, i32 } %lpad.val, i32 %sel, 1 resume { i8*, i32 } %lpad.val29 ``` The `CoroSpit` pass replaces `coro.end` with ``True`` in the resume functions, thus leading to immediate unwind to the caller, whereas in start function it is replaced with ``False``, thus allowing to proceed to the rest of the cleanup code that is only needed during initial invocation of the coroutine. For Windows Exception handling model, a frontend should attach a funclet bundle referring to an enclosing cleanuppad as follows: ``` ehcleanup: %tok = cleanuppad within none [] %unused = call i1 @llvm.coro.end(i8* null, i1 true) [ "funclet"(token %tok) ] cleanupret from %tok unwind label %RestOfTheCleanup ``` The `CoroSplit` pass, if the funclet bundle is present, will insert ``cleanupret from %tok unwind to caller`` before the `coro.end`_ intrinsic and will remove the rest of the block. Reviewers: majnemer Reviewed By: majnemer Subscribers: llvm-commits, mehdi_amini Differential Revision: https://reviews.llvm.org/D25543 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297223 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-30[Coroutines] Add header guard to header that's missing one.Benjamin Kramer
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293494 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-28Cleanup dump() functions.Matthias Braun
We had various variants of defining dump() functions in LLVM. Normalize them (this should just consistently implement the things discussed in http://lists.llvm.org/pipermail/cfe-dev/2014-January/034323.html For reference: - Public headers should just declare the dump() method but not use LLVM_DUMP_METHOD or #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - The definition of a dump method should look like this: #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void MyClass::dump() { // print stuff to dbgs()... } #endif git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293359 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-25[coroutines] Spill the result of the invoke instruction correctlyGor Nishanov
Summary: When we decide that the result of the invoke instruction need to be spilled, we need to insert the spill into a block that is on the normal edge coming out of the invoke instruction. (Prior to this change the code would insert the spill immediately after the invoke instruction, which breaks the IR, since invoke is a terminator instruction). In the following example, we will split the edge going into %cont and insert the spill there. ``` %r = invoke double @print(double 0.0) to label %cont unwind label %pad cont: %0 = call i8 @llvm.coro.suspend(token none, i1 false) switch i8 %0, label %suspend [i8 0, label %resume i8 1, label %cleanup] resume: call double @print(double %r) ``` Reviewers: majnemer Reviewed By: majnemer Subscribers: mehdi_amini, llvm-commits, EricWF Differential Revision: https://reviews.llvm.org/D29102 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293006 91177308-0d34-0410-b5e6-96231b3b80d8
2016-11-20Fix spelling mistakes in Transforms comments. NFC.Simon Pilgrim
Identified by Pedro Giffuni in PR27636. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@287488 91177308-0d34-0410-b5e6-96231b3b80d8
2016-11-17[CMake] NFC. Updating CMake dependency specificationsChris Bieneman
This patch updates a bunch of places where add_dependencies was being explicitly called to add dependencies on intrinsics_gen to instead use the DEPENDS named parameter. This cleanup is needed for a patch I'm working on to add a dependency debugging mode to the build system. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@287206 91177308-0d34-0410-b5e6-96231b3b80d8
2016-10-08[coroutines] Store an address of destroy OR cleanup part in the coroutine frame.Gor Nishanov
Summary: If heap allocation of a coroutine is elided, we need to make sure that we will update an address stored in the coroutine frame from f.destroy to f.cleanup. Before this change, CoroSplit synthesized these stores after coro.begin: ``` store void (%f.Frame*)* @f.resume, void (%f.Frame*)** %resume.addr store void (%f.Frame*)* @f.destroy, void (%f.Frame*)** %destroy.addr ``` In those cases where we did heap elision, but were not able to devirtualize all indirect calls, destroy call will attempt to "free" the coroutine frame stored on the stack. Oops. Now we use select to put an appropriate coroutine subfunction in the destroy slot. As bellow: ``` store void (%f.Frame*)* @f.resume, void (%f.Frame*)** %resume.addr %0 = select i1 %need.alloc, void (%f.Frame*)* @f.destroy, void (%f.Frame*)* @f.cleanup store void (%f.Frame*)* %0, void (%f.Frame*)** %destroy.addr ``` Reviewers: majnemer Subscribers: mehdi_amini, llvm-commits Differential Revision: https://reviews.llvm.org/D25377 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283625 91177308-0d34-0410-b5e6-96231b3b80d8
2016-09-30[Coroutines] Part15c: Fix coro-split to correctly handle definitions between ↵Gor Nishanov
coro.save and coro.suspend Summary: In the case below, %Result.i19 is defined between coro.save and coro.suspend and used after coro.suspend. We need to correctly place such a value into the coroutine frame. ``` %save = call token @llvm.coro.save(i8* null) %Result.i19 = getelementptr inbounds %"struct.lean_future<int>::Awaiter", %"struct.lean_future<int>::Awaiter"* %ref.tmp7, i64 0, i32 0 %suspend = call i8 @llvm.coro.suspend(token %save, i1 false) switch i8 %suspend, label %exit [ i8 0, label %await.ready i8 1, label %exit ] await.ready: %val = load i32, i32* %Result.i19 ``` Reviewers: majnemer Subscribers: llvm-commits, mehdi_amini Differential Revision: https://reviews.llvm.org/D24418 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282902 91177308-0d34-0410-b5e6-96231b3b80d8
2016-09-30[Coroutines] Part15b: Fix dbg information handling in coro-split.Gor Nishanov
Summary: Without the fix, if there was a function inlined into the coroutine with debug information, CloneFunctionInto(NewF, &F, VMap, /*ModuleLevelChanges=*/true, Returns); would duplicate all of the debug information including the DICompileUnit. We know use VMap to indicate that debug metadata for a File, Unit and FunctionType should not be duplicated when we creating clones that will become f.resume, f.destroy and f.cleanup. Reviewers: majnemer Subscribers: mehdi_amini, llvm-commits Differential Revision: https://reviews.llvm.org/D24417 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282899 91177308-0d34-0410-b5e6-96231b3b80d8
2016-09-30[Coroutines] Part 15a: Lower coro.subfn.addr in CoroCleanupGor Nishanov
Summary: Not all coro.subfn.addr intrinsics can be eliminated in CoroElide through devirtualization. Those that remain need to be lowered in CoroCleanup. Reviewers: majnemer Subscribers: llvm-commits, mehdi_amini Differential Revision: https://reviews.llvm.org/D24412 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282897 91177308-0d34-0410-b5e6-96231b3b80d8
2016-09-26[Coroutines] Part14: Handle coroutines with no suspend points.Gor Nishanov
Summary: If coroutine has no suspend points, remove heap allocation and turn a coroutine into a normal function. Also, if a pattern is detected that coroutine resumes or destroys itself prior to coro.suspend call, turn the suspend point into a simple jump to resume or cleanup label. This pattern occurs when coroutines are used to propagate errors in functions that return expected<T>. Reviewers: majnemer Subscribers: mehdi_amini, llvm-commits Differential Revision: https://reviews.llvm.org/D24408 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282414 91177308-0d34-0410-b5e6-96231b3b80d8
2016-09-09[Coroutines] Part13: Handle single edge PHINodes across suspendsGor Nishanov
Summary: If one of the uses of the value is a single edge PHINode, handle it. Original: %val = something <suspend> %p = PHINode [%val] After Spill + Part13: %val = something %slot = gep val.spill.slot store %val, %slot <suspend> %p = load %slot Plus tiny fixes/changes: * use correct index for coro.free in CoroCleanup * fixup id parameter in coro.free to allow authoring coroutine in plain C with __builtins Reviewers: majnemer Subscribers: mehdi_amini, llvm-commits Differential Revision: https://reviews.llvm.org/D24242 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281020 91177308-0d34-0410-b5e6-96231b3b80d8
2016-09-05[Coroutines] Part12: Handle alloca address-takenGor Nishanov
Summary: Move early uses of spilled variables after CoroBegin. For example, if a parameter had address taken, we may end up with the code like: define @f(i32 %n) { %n.addr = alloca i32 store %n, %n.addr ... call @coro.begin This patch fixes the problem by moving uses of spilled variables after CoroBegin. Reviewers: majnemer Subscribers: mehdi_amini, llvm-commits Differential Revision: https://reviews.llvm.org/D24234 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280678 91177308-0d34-0410-b5e6-96231b3b80d8
2016-09-05[Coroutines] Part11: Add final suspend handling.Gor Nishanov
Summary: A frontend may designate a particular suspend to be final, by setting the second argument of the coro.suspend intrinsic to true. Such a suspend point has two properties: * it is possible to check whether a suspended coroutine is at the final suspend point via coro.done intrinsic; * a resumption of a coroutine stopped at the final suspend point leads to undefined behavior. The only possible action for a coroutine at a final suspend point is destroying it via coro.destroy intrinsic. This patch adds final suspend handling logic to CoroEarly and CoroSplit passes. Now, the final suspend point example from docs\Coroutines.rst compiles and produces expected result (see test/Transform/Coroutines/ex5.ll). Reviewers: majnemer Subscribers: mehdi_amini, llvm-commits Differential Revision: https://reviews.llvm.org/D24068 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280646 91177308-0d34-0410-b5e6-96231b3b80d8
2016-08-31[Coroutines] Part 10: Add coroutine promise support.Gor Nishanov
Summary: 1) CoroEarly now lowers llvm.coro.promise intrinsic that allows to obtain a coroutine promise pointer from a coroutine frame and vice versa. 2) CoroFrame now interprets Promise argument of llvm.coro.begin to place CoroutinPromise alloca at a deterministic offset from the coroutine frame. Now, the coroutine promise example from docs\Coroutines.rst compiles and produces expected result (see test/Transform/Coroutines/ex4.ll). Reviewers: majnemer Subscribers: llvm-commits, mehdi_amini Differential Revision: https://reviews.llvm.org/D23993 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280184 91177308-0d34-0410-b5e6-96231b3b80d8
2016-08-29[Coroutines] Part 9: Add cleanup subfunction.Gor Nishanov
Summary: [Coroutines] Part 9: Add cleanup subfunction. This patch completes coroutine heap allocation elision. Now, the heap elision example from docs\Coroutines.rst compiles and produces expected result (see test/Transform/Coroutines/ex3.ll) Intrinsic Changes: * coro.free gets a token parameter tying it to coro.id to allow reliably discovering all coro.frees associated with a particular coroutine. * coro.id gets an extra parameter that points back to a coroutine function. This allows to check whether a coro.id describes the enclosing function or it belongs to a different function that was later inlined. CoroSplit now creates three subfunctions: # f$resume - resume logic # f$destroy - cleanup logic, followed by a deallocation code # f$cleanup - just the cleanup code CoroElide pass during devirtualization replaces coro.destroy with either f$destroy or f$cleanup depending whether heap elision is performed or not. Other fixes, improvements: * Fixed buglet in Shape::buildFrame that was not creating coro.save properly if coroutine has more than one suspend point. * Switched to using variable width suspend index field (no longer limited to 32 bit index field can be as little as i1 or as large as i<whatever-size_t-is>) Reviewers: majnemer Subscribers: llvm-commits, mehdi_amini Differential Revision: https://reviews.llvm.org/D23844 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@279971 91177308-0d34-0410-b5e6-96231b3b80d8
2016-08-24[Coroutines] Fix unused var warning in release buildGor Nishanov
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@279610 91177308-0d34-0410-b5e6-96231b3b80d8
2016-08-24[Coroutines] Part 8: Coroutine Frame Building algorithmGor Nishanov
Summary: This patch adds coroutine frame building algorithm. Now, simple coroutines such as ex0.ll and ex1.ll (first examples from docs\Coroutines.rst can be compiled). Documentation and overview is here: http://llvm.org/docs/Coroutines.html. Upstreaming sequence (rough plan) 1.Add documentation. (https://reviews.llvm.org/D22603) 2.Add coroutine intrinsics. (https://reviews.llvm.org/D22659) ... 7. Split coroutine into subfunctions. (https://reviews.llvm.org/D23461) 8. Coroutine Frame Building algorithm <= we are here 9. Add f.cleanup subfunction. 10+. The rest of the logic Reviewers: majnemer Subscribers: mehdi_amini, llvm-commits Differential Revision: https://reviews.llvm.org/D23586 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@279609 91177308-0d34-0410-b5e6-96231b3b80d8
2016-08-16[Coroutines] Part 7: Split coroutine into subfunctionsGor Nishanov
Summary: This patch adds simple coroutine splitting logic to CoroSplit pass. Documentation and overview is here: http://llvm.org/docs/Coroutines.html. Upstreaming sequence (rough plan) 1.Add documentation. (https://reviews.llvm.org/D22603) 2.Add coroutine intrinsics. (https://reviews.llvm.org/D22659) ... 7. Split coroutine into subfunctions <= we are here 8. Coroutine Frame Building algorithm 9. Handle coroutine with unwinds 10+. The rest of the logic Reviewers: majnemer Subscribers: llvm-commits, mehdi_amini Differential Revision: https://reviews.llvm.org/D23461 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278830 91177308-0d34-0410-b5e6-96231b3b80d8