diff --git a/hpvm/projects/hetero-c++/lib/HPVMCGen.cpp b/hpvm/projects/hetero-c++/lib/HPVMCGen.cpp index 863d0561654e6f072deeb5b4062d3668bf5e7b6e..b750303b53456684b597744fa6317ec4baa0051f 100644 --- a/hpvm/projects/hetero-c++/lib/HPVMCGen.cpp +++ b/hpvm/projects/hetero-c++/lib/HPVMCGen.cpp @@ -178,10 +178,22 @@ CallInst* HPVMCGenBase::insertCallUnchecked(Instruction* insertBefore, } AllocaInst* HPVMCGenBase::insertAlloca(Instruction* insertBefore, std::vector<Value *>& args) { + + // If trying to launch a graph which takes no + // input, return an empty alloca + if(args.empty()){ + LLVM_DEBUG(errs() << "Warning: Attempting to launch a graph which takes 0 inputs ... "<< "\n"); + Type* voidTy = Type::getInt8Ty(theContext.getLLVMContext()); + getIRB().SetInsertPoint(insertBefore); + return getIRB().CreateAlloca(voidTy); + } + std::vector<Type *> argTypesVec; for(auto *argument : args) { argTypesVec.push_back(argument->getType()); } + + ArrayRef<Type *> argTypes(argTypesVec); StructType *StructTy = StructType::create(argTypes, "DFGArgs", true); diff --git a/hpvm/projects/hetero-c++/test/unit/hetero-host/happy/empty_launch.cc b/hpvm/projects/hetero-c++/test/unit/hetero-host/happy/empty_launch.cc new file mode 100644 index 0000000000000000000000000000000000000000..b4e80d15b34dbddebf9897f44aa0f820e85182fb --- /dev/null +++ b/hpvm/projects/hetero-c++/test/unit/hetero-host/happy/empty_launch.cc @@ -0,0 +1,35 @@ +#include "heterocc.h" +#include <stdlib.h> +#include <stdio.h> + + + + +void RootFn() +{ + auto s = __hetero_section_begin(); + + for(int i = 0 ; i < 100; i++){ + __hetero_parallel_loop(1, 0, 0, "empty_loop"); + printf("Hello World!\n"); + } + + __hetero_section_end(s); + +} + + +int main(){ + + + void* DFG = __hetero_launch((void*) RootFn, + 0, 0); + + + __hetero_wait(DFG); + + + + + return 0; +} diff --git a/hpvm/projects/hetero-c++/test/unit/hetero_pass/hetero-host/empty_launch.ll b/hpvm/projects/hetero-c++/test/unit/hetero_pass/hetero-host/empty_launch.ll new file mode 100644 index 0000000000000000000000000000000000000000..e995cec0816b6b39b5bdb791980b938f9649cb4a --- /dev/null +++ b/hpvm/projects/hetero-c++/test/unit/hetero_pass/hetero-host/empty_launch.ll @@ -0,0 +1,72 @@ +; RUN: hcc -declsfile ../tools/hpvm/projects/hetero-c++/lib/HPVMCFunctionDeclarations/HPVMCFunctionDeclarations.bc -control-only -S < %s | FileCheck %s +; ModuleID = 'happy/empty_launch.cc' +source_filename = "happy/empty_launch.cc" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@.str = private unnamed_addr constant [11 x i8] c"empty_loop\00", align 1 +@str = private unnamed_addr constant [13 x i8] c"Hello World!\00", align 1 + +; CHECK-LABEL: i32 @main( +; CHECK: call void @__hpvm__init() +; CHECK: %0 = alloca i8, align 1 +; CHECK: %__hpvm__launch = call i8* (i32, ...) @__hpvm__launch(i32 0, void ()* @_Z6RootFnv, i8* %0) +; CHECK: call void @__hpvm__wait(i8* %__hpvm__launch) +; CHECK: call void @__hpvm__cleanup() + +; Function Attrs: mustprogress uwtable +define dso_local void @_Z6RootFnv() #0 { +entry: + %call = call i8* @__hetero_section_begin() + br label %for.body + +for.cond.cleanup: ; preds = %for.body + call void @__hetero_section_end(i8* %call) + ret void + +for.body: ; preds = %entry, %for.body + %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + call void (i32, ...) @__hetero_parallel_loop(i32 1, i32 0, i32 0, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0)) + %puts = call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([13 x i8], [13 x i8]* @str, i64 0, i64 0)) + %inc = add nuw nsw i32 %i.05, 1 + %exitcond.not = icmp eq i32 %inc, 100 + br i1 %exitcond.not, label %for.cond.cleanup, label %for.body, !llvm.loop !3 +} + +declare dso_local i8* @__hetero_section_begin() local_unnamed_addr #1 + +declare dso_local void @__hetero_parallel_loop(i32, ...) local_unnamed_addr #1 + +declare dso_local void @__hetero_section_end(i8*) local_unnamed_addr #1 + + + +; Function Attrs: mustprogress norecurse uwtable +define dso_local i32 @main() local_unnamed_addr #2 { +entry: + %call = call i8* (i8*, ...) @__hetero_launch(i8* bitcast (void ()* @_Z6RootFnv to i8*), i32 0, i32 0) + call void @__hetero_wait(i8* %call) + ret i32 0 +} + +declare dso_local i8* @__hetero_launch(i8*, ...) local_unnamed_addr #1 + +declare dso_local void @__hetero_wait(i8*) local_unnamed_addr #1 + +; Function Attrs: nofree nounwind +declare noundef i32 @puts(i8* nocapture noundef readonly) local_unnamed_addr #3 + +attributes #0 = { mustprogress uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #2 = { mustprogress norecurse uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { nofree nounwind } + +!llvm.module.flags = !{!0, !1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"uwtable", i32 1} +!2 = !{!"clang version 13.0.0 (https://gitlab.engr.illinois.edu/llvm/hpvm.git 19bf92289531ec07aff279c436faf9c5821e1f66)"} +!3 = distinct !{!3, !4, !5} +!4 = !{!"llvm.loop.mustprogress"} +!5 = !{!"llvm.loop.unroll.disable"}