Skip to content

Commit

Permalink
[TapirUtils] Fix logic to insert fixups for outputs of taskframes.
Browse files Browse the repository at this point in the history
- Fix crash when inserting taskframe fixups for a taskframe with no continuation.
- Ensure that allocas for taskframe fixups are properly inserted within the parent taskframe.
- Avoid inserting taskframe load guards for unassociated taskframes.
  • Loading branch information
neboat committed Dec 7, 2024
1 parent 2233241 commit ebc6f7f
Show file tree
Hide file tree
Showing 19 changed files with 410 additions and 67 deletions.
7 changes: 7 additions & 0 deletions llvm/include/llvm/Analysis/TapirTaskInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include <utility>

namespace llvm {
Expand Down Expand Up @@ -101,6 +102,12 @@ class Spindle {
++D;
return D;
}
BasicBlock::iterator getTaskFrameFirstInsertionPt() {
if (Instruction *TFCreate =
dyn_cast_or_null<Instruction>(getTaskFrameCreate()))
return TFCreate->getNextNode()->getIterator();
return getEntry()->getFirstInsertionPt();
}

Task *getTaskFromTaskFrame() const;

Expand Down
60 changes: 37 additions & 23 deletions llvm/lib/Transforms/Utils/TapirUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
#include "llvm/IR/Dominators.h"
#include "llvm/IR/EHPersonalities.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/Casting.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/Local.h"
Expand Down Expand Up @@ -1003,6 +1005,10 @@ void llvm::SerializeDetach(DetachInst *DI, BasicBlock *ParentEntry,
// Erase instructions marked to be erased.
for (Instruction *I : ToErase)
I->eraseFromParent();
if (ReplaceWithTaskFrame && TaskFrame && TaskFrame->use_empty())
cast<Instruction>(TaskFrame)->eraseFromParent();
if (isa_and_nonnull<Instruction>(SyncRegion) && SyncRegion->use_empty())
cast<Instruction>(SyncRegion)->eraseFromParent();

// Update dominator tree.
if (DT) {
Expand Down Expand Up @@ -1765,12 +1771,12 @@ void llvm::fixupTaskFrameExternalUses(Spindle *TF, const TaskInfo &TI,
return;
Task *T = TF->getTaskFrameUser();

LLVM_DEBUG(dbgs() << "fixupTaskFrameExternalUses: spindle@"
<< TF->getEntry()->getName() << "\n");
LLVM_DEBUG({
if (T)
dbgs() << " used by task@" << T->getEntry()->getName() << "\n";
});
dbgs() << "fixupTaskFrameExternalUses: spindle@"
<< TF->getEntry()->getName() << "\n";
if (T)
dbgs() << " used by task@" << T->getEntry()->getName() << "\n";
});

// Get the set of basic blocks in the taskframe spindles. At the same time,
// find the continuation of corresponding taskframe.resume intrinsics.
Expand Down Expand Up @@ -1880,12 +1886,11 @@ void llvm::fixupTaskFrameExternalUses(Spindle *TF, const TaskInfo &TI,
for (auto &TFInstr : ToRewrite) {
LLVM_DEBUG(dbgs() << "Fixing taskframe output " << *TFInstr.first << "\n");
// Create an allocation to store the result of the instruction.
BasicBlock *ParentEntry;
if (Spindle *ParentTF = TF->getTaskFrameParent())
ParentEntry = ParentTF->getEntry();
else
ParentEntry = TF->getParentTask()->getEntry();
IRBuilder<> Builder(&*ParentEntry->getFirstInsertionPt());
Spindle *ParentS = TF->getTaskFrameParent()
? TF->getTaskFrameParent()
: TF->getParentTask()->getEntrySpindle();
BasicBlock::iterator ParentInsertionPt = ParentS->getTaskFrameFirstInsertionPt();
IRBuilder<> Builder(&*ParentInsertionPt);
Type *TFInstrTy = TFInstr.first->getType();
AllocaInst *AI = Builder.CreateAlloca(TFInstrTy);
AI->setName(TFInstr.first->getName());
Expand All @@ -1898,13 +1903,18 @@ void llvm::fixupTaskFrameExternalUses(Spindle *TF, const TaskInfo &TI,
Builder.SetInsertPoint(&*(++TFInstr.first->getIterator()));
Builder.CreateStore(TFInstr.first, AI);

// Load the result of the instruction at the continuation.
Builder.SetInsertPoint(&*Continuation->getFirstInsertionPt());
Builder.CreateCall(
Intrinsic::getDeclaration(M, Intrinsic::taskframe_load_guard,
{ AI->getType() }), { AI });
LoadInst *ContinVal = Builder.CreateLoad(TFInstrTy, AI);
LoadInst *ContinVal = nullptr;
LoadInst *EHContinVal = nullptr;
// Load the result of the instruction at the continuation.
if (Continuation) {
Builder.SetInsertPoint(&*Continuation->getFirstInsertionPt());
if (T)
Builder.CreateCall(
Intrinsic::getDeclaration(M, Intrinsic::taskframe_load_guard,
{AI->getType()}),
{AI});
ContinVal = Builder.CreateLoad(TFInstrTy, AI);
}

// For each external use, replace the use with a load from the alloca.
for (Use *UseToRewrite : TFInstr.second) {
Expand All @@ -1919,9 +1929,11 @@ void llvm::fixupTaskFrameExternalUses(Spindle *TF, const TaskInfo &TI,
// If necessary, load the value at the taskframe.resume continuation.
if (!EHContinVal) {
Builder.SetInsertPoint(&*(TFResumeContin->getFirstInsertionPt()));
Builder.CreateCall(
Intrinsic::getDeclaration(M, Intrinsic::taskframe_load_guard,
{ AI->getType() }), { AI });
if (T)
Builder.CreateCall(
Intrinsic::getDeclaration(M, Intrinsic::taskframe_load_guard,
{AI->getType()}),
{AI});
EHContinVal = Builder.CreateLoad(TFInstrTy, AI);
}

Expand All @@ -1933,9 +1945,11 @@ void llvm::fixupTaskFrameExternalUses(Spindle *TF, const TaskInfo &TI,
}

// Rewrite to use the value loaded at the continuation.
if (UseToRewrite->get()->hasValueHandle())
ValueHandleBase::ValueIsRAUWd(*UseToRewrite, ContinVal);
UseToRewrite->set(ContinVal);
if (ContinVal) {
if (UseToRewrite->get()->hasValueHandle())
ValueHandleBase::ValueIsRAUWd(*UseToRewrite, ContinVal);
UseToRewrite->set(ContinVal);
}
}
}
}
Expand Down
161 changes: 161 additions & 0 deletions llvm/test/Transforms/Tapir/alloca-insert-split-taskframe.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
; RUN: opt < %s -passes="tapir2target" -tapir-target=opencilk -use-opencilk-runtime-bc=false -debug-abi-calls -S | FileCheck %s

target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

%"struct.parlay::sequence_internal::sequence_base<double, parlay::allocator<double>, false>::storage_impl::capacitated_buffer::header" = type { i64, %union.anon.229 }
%union.anon.229 = type { [1 x i8], [7 x i8] }

; Function Attrs: nounwind willreturn memory(argmem: readwrite)
declare token @llvm.syncregion.start() #0

; Function Attrs: nounwind willreturn memory(argmem: readwrite)
declare token @llvm.tapir.runtime.start() #0

; Function Attrs: nounwind willreturn memory(argmem: readwrite)
declare token @llvm.taskframe.create() #0

; Function Attrs: nounwind willreturn memory(argmem: readwrite)
declare void @llvm.tapir.runtime.end(token) #0

; Function Attrs: nounwind willreturn memory(argmem: readwrite)
declare void @llvm.taskframe.end(token) #0

define fastcc void @_Z6kmeansIFdRKN6parlay8sequenceIdNS0_9allocatorIdEELb0EEES6_EEDaRNS1_IS4_NS2_IS4_EELb0EEEiRT_d.outline_pfor.cond.i.i.i182.ls2(ptr %call.i.i.i.i31.i874.ls2) personality ptr null {
invoke.cont61.tf.i.i.ls2:
%syncreg15.i.i.i.i.i.ls2 = tail call token @llvm.syncregion.start()
%0 = tail call token @llvm.syncregion.start()
%tf.i.i.i.i.ls2 = call token @llvm.taskframe.create()
%1 = call token @llvm.tapir.runtime.start()
call void @llvm.tapir.runtime.end(token %1)
%tf.i872.ls2 = call token @llvm.taskframe.create()
%2 = getelementptr %"struct.parlay::sequence_internal::sequence_base<double, parlay::allocator<double>, false>::storage_impl::capacitated_buffer::header", ptr %call.i.i.i.i31.i874.ls2, i64 0, i32 1
%3 = call token @llvm.tapir.runtime.start()
detach within %syncreg15.i.i.i.i.i.ls2, label %det.achd.i.i.ls2, label %det.cont.i.i.ls2 unwind label %lpad17.i.i.ls2

vector.ph3079.ls2: ; No predecessors!
%4 = getelementptr double, ptr %2, i64 0
br label %invoke.cont.i.i.i.i.i266.i.i.ls2

invoke.cont.i.i.i.i.i266.i.i.ls2: ; preds = %det.cont.i.i.ls2, %vector.ph3079.ls2
call void @llvm.taskframe.end(token %tf.i872.ls2)
%tf.i1536.ls2 = call token @llvm.taskframe.create()
%5 = call token @llvm.tapir.runtime.start()
detach within %syncreg15.i.i.i.i.i.ls2, label %det.achd.i.i1532.ls2, label %det.cont.i.i1526.ls2 unwind label %lpad17.i.i1523.ls2

det.cont.i.i1526.ls2: ; preds = %det.achd.i.i1532.ls2, %invoke.cont.i.i.i.i.i266.i.i.ls2
sync within %syncreg15.i.i.i.i.i.ls2, label %sync.continue28.i.i1530.ls2

sync.continue28.i.i1530.ls2: ; preds = %det.cont.i.i1526.ls2
call void @llvm.taskframe.end(token %tf.i1536.ls2)
call void @llvm.taskframe.end(token %tf.i.i.i.i.ls2)
ret void

lpad17.i.i1523.ls2: ; preds = %invoke.cont.i.i.i.i.i266.i.i.ls2
%6 = landingpad { ptr, i32 }
cleanup
call void @llvm.tapir.runtime.end(token %5)
unreachable

det.cont.i.i.ls2: ; preds = %det.achd.i.i.ls2, %invoke.cont61.tf.i.i.ls2
sync within %syncreg15.i.i.i.i.i.ls2, label %invoke.cont.i.i.i.i.i266.i.i.ls2

lpad17.i.i.ls2: ; preds = %invoke.cont61.tf.i.i.ls2
%7 = landingpad { ptr, i32 }
cleanup
call void @llvm.tapir.runtime.end(token %3)
unreachable

det.achd.i.i1532.ls2: ; preds = %invoke.cont.i.i.i.i.i266.i.i.ls2
reattach within %syncreg15.i.i.i.i.i.ls2, label %det.cont.i.i1526.ls2

det.achd.i.i.ls2: ; preds = %invoke.cont61.tf.i.i.ls2
reattach within %syncreg15.i.i.i.i.i.ls2, label %det.cont.i.i.ls2
}

; CHECK-LABEL: define {{.*}}void @_Z6kmeansIFdRKN6parlay8sequenceIdNS0_9allocatorIdEELb0EEES6_EEDaRNS1_IS4_NS2_IS4_EELb0EEEiRT_d.outline_pfor.cond.i.i.i182.ls2(ptr %call.i.i.i.i31.i874.ls2)
; CHECK: invoke.cont61.tf.i.i.ls2:
; CHECK-NEXT: %[[FIXUP_ALLOCA:.+]] = alloca ptr
; CHECK-NEXT: call token @llvm.syncregion.start()
; CHECK-NEXT: call token @llvm.syncregion.start()
; CHECK-NEXT: call {{.*}}void @_Z6kmeansIFdRKN6parlay8sequenceIdNS0_9allocatorIdEELb0EEES6_EEDaRNS1_IS4_NS2_IS4_EELb0EEEiRT_d.outline_pfor.cond.i.i.i182.ls2.outline_invoke.cont61.tf.i.i.ls2.tf.otf0(ptr %call.i.i.i.i31.i874.ls2, ptr %[[FIXUP_ALLOCA]])
; CHECK-NEXT: br label %sync.continue28.i.i1530.ls2.tfend

; CHECK: sync.continue28.i.i1530.ls2.tfend:
; CHECK: ret void

; CHECK-LABEL: define {{.*}}void @_Z6kmeansIFdRKN6parlay8sequenceIdNS0_9allocatorIdEELb0EEES6_EEDaRNS1_IS4_NS2_IS4_EELb0EEEiRT_d.outline_pfor.cond.i.i.i182.ls2.outline_det.achd.i.i.ls2.otd1
; CHECK: (ptr %[[ARG:.+]])
; CHECK: call void @__cilkrts_detach(
; CHECK: ret void

; CHECK-LABEL: define {{.*}}void @_Z6kmeansIFdRKN6parlay8sequenceIdNS0_9allocatorIdEELb0EEES6_EEDaRNS1_IS4_NS2_IS4_EELb0EEEiRT_d.outline_pfor.cond.i.i.i182.ls2.outline_invoke.cont61.tf.i.i.ls2.tf.tf.otf1(ptr {{.*}}%call.i.i.i.i31.i874.ls2.otf1,
; CHECK: ptr {{.*}}%[[ARG:.+]])

; CHECK: invoke.cont61.tf.i.i.ls2.tf.tf.otf1:
; CHECK: %[[ADDR:.+]] = getelementptr %"struct.parlay::sequence_internal::sequence_base<double, parlay::allocator<double>, false>::storage_impl::capacitated_buffer::header", ptr %call.i.i.i.i31.i874.ls2.otf1, i64 0, i32 1
; CHECK-NEXT: store ptr %[[ADDR]], ptr %[[ARG]]
; CHECK-NEXT: call void @__cilkrts_enter_frame(
; CHECK-NEXT: %[[TAPIR_RT_START:.+]] = call token @llvm.tapir.runtime.start()
; CHECK-NEXT: call i32 @__cilk_prepare_spawn(

; CHECK: invoke {{.*}}void @_Z6kmeansIFdRKN6parlay8sequenceIdNS0_9allocatorIdEELb0EEES6_EEDaRNS1_IS4_NS2_IS4_EELb0EEEiRT_d.outline_pfor.cond.i.i.i182.ls2.outline_det.achd.i.i.ls2.otd1(
; CHECK-NEXT: to label %det.cont.i.i.ls2.otf1 unwind label %lpad17.i.i.ls2.otf1

; CHECK: lpad17.i.i.ls2.otf1:
; CHECK: landingpad
; CHECK: call void @llvm.tapir.runtime.end(token %[[TAPIR_RT_START]])
; CHECK-NEXT: unreachable

; CHECK: det.cont.i.i.ls2.otf1:
; CHECK-NEXT: call void @__cilk_sync(

; CHECK: ret void

; CHECK-LABEL: define {{.*}}void @_Z6kmeansIFdRKN6parlay8sequenceIdNS0_9allocatorIdEELb0EEES6_EEDaRNS1_IS4_NS2_IS4_EELb0EEEiRT_d.outline_pfor.cond.i.i.i182.ls2.outline_det.achd.i.i1532.ls2.otd1(
; CHECK: (ptr %[[ARG:.+]])
; CHECK: call void @__cilkrts_detach(
; CHECK: ret void

; CHECK-LABEL: define {{.*}}void @_Z6kmeansIFdRKN6parlay8sequenceIdNS0_9allocatorIdEELb0EEES6_EEDaRNS1_IS4_NS2_IS4_EELb0EEEiRT_d.outline_pfor.cond.i.i.i182.ls2.outline_invoke.cont.i.i.i.i.i266.i.i.ls2.tf.otf1()
; CHECK: invoke.cont.i.i.i.i.i266.i.i.ls2.tf.otf1:
; CHECK: call void @__cilkrts_enter_frame(
; CHECK-NEXT: %[[TAPIR_RT_START:.+]] = call token @llvm.tapir.runtime.start()
; CHECK-NEXT: call i32 @__cilk_prepare_spawn(

; CHECK: invoke {{.*}}void @_Z6kmeansIFdRKN6parlay8sequenceIdNS0_9allocatorIdEELb0EEES6_EEDaRNS1_IS4_NS2_IS4_EELb0EEEiRT_d.outline_pfor.cond.i.i.i182.ls2.outline_det.achd.i.i1532.ls2.otd1(
; CHECK-NEXT: to label %det.cont.i.i1526.ls2.otf1 unwind label %lpad17.i.i1523.ls2.otf1

; CHECK: lpad17.i.i1523.ls2.otf1:
; CHECK-NEXT: landingpad
; CHECK: call void @llvm.tapir.runtime.end(token %[[TAPIR_RT_START]])
; CHECK-NEXT: unreachable

; CHECK: det.cont.i.i1526.ls2.otf1:
; CHECK-NEXT: call void @__cilk_sync(

; CHECK: ret void

; CHECK-LABEL: define {{.*}}void @_Z6kmeansIFdRKN6parlay8sequenceIdNS0_9allocatorIdEELb0EEES6_EEDaRNS1_IS4_NS2_IS4_EELb0EEEiRT_d.outline_pfor.cond.i.i.i182.ls2.outline_invoke.cont61.tf.i.i.ls2.tf.otf0(ptr align 1 %call.i.i.i.i31.i874.ls2.otf0,
; CHECK: ptr {{.*}}%[[ARG:.+]])
; CHECK: %[[FIXUP_ALLOCA:.+]] = alloca ptr

; CHECK: call void @llvm.lifetime.start.p0(i64 8, ptr %[[FIXUP_ALLOCA]])
; CHECK-NEXT: call void @__cilkrts_enter_frame(
; CHECK-NEXT: %[[TAPIR_RT_START:.+]] = call token @llvm.tapir.runtime.start()
; CHECK-NEXT: call void @__cilk_parent_epilogue(
; CHECK-NEXT: call void @llvm.tapir.runtime.end(token %[[TAPIR_RT_START]])
; CHECK-NEXT: call {{.*}}void @_Z6kmeansIFdRKN6parlay8sequenceIdNS0_9allocatorIdEELb0EEES6_EEDaRNS1_IS4_NS2_IS4_EELb0EEEiRT_d.outline_pfor.cond.i.i.i182.ls2.outline_invoke.cont61.tf.i.i.ls2.tf.tf.otf1(ptr %call.i.i.i.i31.i874.ls2.otf0, ptr %[[FIXUP_ALLOCA]])

; CHECK: %[[FIXUP_LOAD:.+]] = load ptr, ptr %[[FIXUP_ALLOCA]]
; CHECK-NEXT: store ptr %[[FIXUP_LOAD]], ptr %[[ARG]]
; CHECK-NEXT: call {{.*}}void @_Z6kmeansIFdRKN6parlay8sequenceIdNS0_9allocatorIdEELb0EEES6_EEDaRNS1_IS4_NS2_IS4_EELb0EEEiRT_d.outline_pfor.cond.i.i.i182.ls2.outline_invoke.cont.i.i.i.i.i266.i.i.ls2.tf.otf1()

; CHECK: call void @llvm.lifetime.end.p0(i64 8, ptr %[[FIXUP_ALLOCA]])

; CHECK: ret void

; uselistorder directives
uselistorder ptr null, { 1, 2, 0 }

attributes #0 = { nounwind willreturn memory(argmem: readwrite) }
13 changes: 9 additions & 4 deletions llvm/test/Transforms/Tapir/inline-detach-unwind.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
target triple = "arm64-apple-macosx15.0.0"

; Function Attrs: nounwind willreturn memory(argmem: readwrite)
declare token @llvm.syncregion.start() #0

; CHECK: define void @_ZNK5Graph17pbfs_walk_PennantEP7PennantIiERH3BagIiEjPj()

; CHECK: pfor.cond:
; CHECK-NEXT: detach within none, label %pfor.body.entry, label %pfor.cond unwind label %lpad59
; CHECK-NEXT: detach within %syncreg, label %pfor.body.entry, label %pfor.cond unwind label %lpad59

; CHECK: pfor.body.entry:
; CHECK: br label %[[INLINED_PFOR_COND:.+]]
Expand All @@ -25,18 +28,19 @@ target triple = "arm64-apple-macosx15.0.0"

define void @_ZNK5Graph17pbfs_walk_PennantEP7PennantIiERH3BagIiEjPj() personality ptr null {
entry:
%syncreg = tail call token @llvm.syncregion.start()
%0 = call token @llvm.tapir.runtime.start()
br label %pfor.cond

pfor.cond: ; preds = %pfor.preattach, %pfor.cond, %entry
detach within none, label %pfor.body.entry, label %pfor.cond unwind label %lpad59
detach within %syncreg, label %pfor.body.entry, label %pfor.cond unwind label %lpad59

pfor.body.entry: ; preds = %pfor.cond
invoke fastcc void @_ZL14pbfs_proc_NodePKiiRH3BagIiEjPjS0_S0_(ptr null, i32 0, ptr null, i32 0, ptr null, ptr null, ptr null)
to label %pfor.preattach unwind label %lpad49

pfor.preattach: ; preds = %pfor.body.entry
reattach within none, label %pfor.cond
reattach within %syncreg, label %pfor.cond

lpad49: ; preds = %pfor.body.entry
%1 = landingpad { ptr, i32 }
Expand All @@ -52,10 +56,11 @@ lpad59: ; preds = %pfor.cond

define fastcc void @_ZL14pbfs_proc_NodePKiiRH3BagIiEjPjS0_S0_(ptr %n, i32 %fillSize, ptr %next, i32 %newdist, ptr %distances, ptr %nodes, ptr %edges) personality ptr null {
entry:
%syncreg = tail call token @llvm.syncregion.start()
br label %pfor.cond

pfor.cond: ; preds = %pfor.cond, %entry
detach within none, label %pfor.body.entry, label %pfor.cond unwind label %lpad20
detach within %syncreg, label %pfor.body.entry, label %pfor.cond unwind label %lpad20

pfor.body.entry: ; preds = %pfor.cond
br label %for.cond
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ for.cond86: ; preds = %for.cond86, %entry

; CHECK: [[IF_ELSE_I]]:
; CHECK-NEXT: %[[TF_I:.+]] = call token @llvm.taskframe.create()
; CHECK-NEXT: %syncreg19.i.i3 = call token @llvm.syncregion.start()
; CHECK-NEXT: detach within %syncreg19.i.i3, label %det.achd.i.i, label
; CHECK: %syncreg19.i.i5 = call token @llvm.syncregion.start()
; CHECK-NEXT: detach within %syncreg19.i.i5, label %det.achd.i.i, label
; CHECK-NOT: unwind label

; CHECK: det.achd.i.i:
; CHECK-NEXT: reattach within %syncreg19.i.i3, label
; CHECK-NEXT: reattach within %syncreg19.i.i5, label

lpad90: ; preds = %for.cond86
%0 = landingpad { ptr, i32 }
Expand All @@ -53,27 +53,29 @@ if.else: ; preds = %entry

define linkonce_odr void @_ZN6parlay12parallel_forIZN4gbbs9vertexMapINS1_16vertexSubsetDataINS1_5emptyEEENS1_2bc37SSBetweennessCentrality_Back_Vertex_FINS_8sequenceIbSaIbELb0EEENS8_IdSaIdELb0EEEEELi0EEEvRT_T0_mEUlmE_EEvmmOSE_lb() {
entry:
detach within none, label %pfor.body.entry, label %pfor.inc
%syncreg = tail call token @llvm.syncregion.start()
detach within %syncreg, label %pfor.body.entry, label %pfor.inc

pfor.body.entry: ; preds = %entry
reattach within none, label %pfor.inc
reattach within %syncreg, label %pfor.inc

pfor.inc: ; preds = %pfor.body.entry, %entry
ret void
}

define linkonce_odr void @_ZN6parlay12parallel_forIZN4gbbs9vertexMapINS1_16vertexSubsetDataINS1_5emptyEEENS1_2bc37SSBetweennessCentrality_Back_Vertex_FINS_8sequenceIbSaIbELb0EEENS8_IdSaIdELb0EEEEELi0EEEvRT_T0_mEUlmE0_EEvmmOSE_lb(i64 %granularity) {
entry:
%syncreg = tail call token @llvm.syncregion.start()
%syncreg19 = call token @llvm.syncregion.start()
%cmp = icmp eq i64 %granularity, 0
br i1 %cmp, label %pfor.cond, label %if.else

pfor.cond: ; preds = %pfor.body.entry, %pfor.cond, %entry
detach within none, label %pfor.body.entry, label %pfor.cond
detach within %syncreg, label %pfor.body.entry, label %pfor.cond

pfor.body.entry: ; preds = %pfor.cond
call void @_ZZN4gbbs9vertexMapINS_16vertexSubsetDataINS_5emptyEEENS_2bc37SSBetweennessCentrality_Back_Vertex_FIN6parlay8sequenceIbSaIbELb0EEENS7_IdSaIdELb0EEEEELi0EEEvRT_T0_mENKUlmE0_clEm()
reattach within none, label %pfor.cond
reattach within %syncreg, label %pfor.cond

if.else: ; preds = %entry
detach within %syncreg19, label %det.achd, label %det.cont
Expand Down
Loading

0 comments on commit ebc6f7f

Please sign in to comment.