Skip to content

Commit e16fbd5

Browse files
committed
CodeGen: Place OmpSs-2 task's allocas at the beginning of the task instead of the beginning of the function
Closes llvm#32
1 parent 31a84bb commit e16fbd5

File tree

4 files changed

+106
-6
lines changed

4 files changed

+106
-6
lines changed

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "CGDebugInfo.h"
1818
#include "CGObjCRuntime.h"
1919
#include "CGOpenMPRuntime.h"
20+
#include "CGOmpSsRuntime.h"
2021
#include "CGRecordLayout.h"
2122
#include "CodeGenFunction.h"
2223
#include "CodeGenModule.h"
@@ -108,6 +109,11 @@ llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(llvm::Type *Ty,
108109
llvm::Value *ArraySize) {
109110
if (ArraySize)
110111
return Builder.CreateAlloca(Ty, ArraySize, Name);
112+
if (getLangOpts().OmpSs && CGM.getOmpSsRuntime().inTask())
113+
return new llvm::AllocaInst(Ty, CGM.getDataLayout().getAllocaAddrSpace(),
114+
ArraySize, Name,
115+
CGM.getOmpSsRuntime().getCurrentTask());
116+
111117
return new llvm::AllocaInst(Ty, CGM.getDataLayout().getAllocaAddrSpace(),
112118
ArraySize, Name, AllocaInsertPt);
113119
}

clang/lib/CodeGen/CGOmpSsRuntime.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,14 @@ void CGOmpSsRuntime::emitTaskwaitCall(CodeGenFunction &CGF,
350350
"TASKWAIT"))});
351351
}
352352

353+
bool CGOmpSsRuntime::inTask() {
354+
return !TaskEntryStack.empty();
355+
}
356+
357+
llvm::AssertingVH<llvm::Instruction> CGOmpSsRuntime::getCurrentTask() {
358+
return TaskEntryStack.back();
359+
}
360+
353361
void CGOmpSsRuntime::emitTaskCall(CodeGenFunction &CGF,
354362
const OSSExecutableDirective &D,
355363
SourceLocation Loc,
@@ -386,14 +394,21 @@ void CGOmpSsRuntime::emitTaskCall(CodeGenFunction &CGF,
386394
EmitDependency("QUAL.OSS.DEP.WEAKINOUT", CGF, E, TaskInfo);
387395
}
388396

389-
llvm::Value *Result =
390-
CGF.Builder.CreateCall(EntryCallee,
391-
{},
392-
llvm::makeArrayRef(TaskInfo));
397+
llvm::Instruction *Result =
398+
CGF.Builder.CreateCall(EntryCallee, {}, llvm::makeArrayRef(TaskInfo));
399+
400+
// Push Task Stack
401+
llvm::Value *Undef = llvm::UndefValue::get(CGF.Int32Ty);
402+
llvm::Instruction *TaskAllocaInsertPt = new llvm::BitCastInst(Undef, CGF.Int32Ty, "taskallocapt", Result->getParent());
403+
TaskEntryStack.push_back(TaskAllocaInsertPt);
393404

394405
CGF.EmitStmt(D.getAssociatedStmt());
395406

396-
CGF.Builder.CreateCall(ExitCallee,
397-
Result);
407+
CGF.Builder.CreateCall(ExitCallee, Result);
408+
409+
// Pop Task Stack
410+
TaskEntryStack.pop_back();
411+
TaskAllocaInsertPt->eraseFromParent();
412+
398413
}
399414

clang/lib/CodeGen/CGOmpSsRuntime.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,22 @@ class CGOmpSsRuntime {
4848
protected:
4949
CodeGenModule &CGM;
5050

51+
private:
52+
SmallVector<llvm::AssertingVH<llvm::Instruction>, 2> TaskEntryStack;
53+
5154
public:
5255
explicit CGOmpSsRuntime(CodeGenModule &CGM) : CGM(CGM) {}
5356
virtual ~CGOmpSsRuntime() {};
5457
virtual void clear() {};
5558

59+
// returns true if we're emitting code inside a task context (entry/exit)
60+
bool inTask();
61+
// returns the innermost nested task entry mark instruction
62+
llvm::AssertingVH<llvm::Instruction> getCurrentTask();
63+
5664
/// Emit code for 'taskwait' directive.
5765
virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc);
66+
/// Emit code for 'task' directive.
5867
virtual void emitTaskCall(CodeGenFunction &CGF,
5968
const OSSExecutableDirective &D,
6069
SourceLocation Loc,
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// RUN: %clang_cc1 -verify -fompss-2 -ferror-limit 100 %s -S -emit-llvm -o - | FileCheck %s
2+
// expected-no-diagnostics
3+
4+
void foo(int x) {
5+
int a, b, c;
6+
int va[x];
7+
#pragma oss task firstprivate(x)
8+
{
9+
int d, e, f;
10+
int va1[x];
11+
#pragma oss task
12+
{
13+
int g, h, i;
14+
}
15+
}
16+
#pragma oss task
17+
{
18+
int j, k, l;
19+
}
20+
int m;
21+
}
22+
23+
// CHECK: %x.addr = alloca i32, align 4
24+
// CHECK-NEXT: %a = alloca i32, align 4
25+
// CHECK-NEXT: %b = alloca i32, align 4
26+
// CHECK-NEXT: %c = alloca i32, align 4
27+
// CHECK-NEXT: %saved_stack = alloca i8*, align 8
28+
// CHECK-NEXT: %__vla_expr0 = alloca i64, align 8
29+
// CHECK-NEXT: %m = alloca i32, align 4
30+
// CHECK-NEXT: store i32 %x, i32* %x.addr, align 4
31+
// CHECK-NEXT: %0 = load i32, i32* %x.addr, align 4
32+
// CHECK-NEXT: %1 = zext i32 %0 to i64
33+
// CHECK-NEXT: %2 = call i8* @llvm.stacksave()
34+
// CHECK-NEXT: store i8* %2, i8** %saved_stack, align 8
35+
// CHECK-NEXT: %vla = alloca i32, i64 %1, align 16
36+
// CHECK-NEXT: store i64 %1, i64* %__vla_expr0, align 8
37+
38+
// CHECK: %3 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.FIRSTPRIVATE"(i32* %x.addr) ]
39+
// CHECK-NEXT: %d = alloca i32, align 4
40+
// CHECK-NEXT: %e = alloca i32, align 4
41+
// CHECK-NEXT: %f = alloca i32, align 4
42+
// CHECK-NEXT: %saved_stack1 = alloca i8*, align 8
43+
// CHECK-NEXT: %__vla_expr1 = alloca i64, align 8
44+
// CHECK-NEXT: %4 = load i32, i32* %x.addr, align 4
45+
// CHECK-NEXT: %5 = zext i32 %4 to i64
46+
// CHECK-NEXT: %6 = call i8* @llvm.stacksave()
47+
// CHECK-NEXT: store i8* %6, i8** %saved_stack1, align 8
48+
// CHECK-NEXT: %vla2 = alloca i32, i64 %5, align 16
49+
// CHECK-NEXT: store i64 %5, i64* %__vla_expr1, align 8
50+
51+
// CHECK: %7 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00") ]
52+
// CHECK-NEXT: %g = alloca i32, align 4
53+
// CHECK-NEXT: %h = alloca i32, align 4
54+
// CHECK-NEXT: %i = alloca i32, align 4
55+
// CHECK-NEXT: call void @llvm.directive.region.exit(token %7)
56+
57+
// CHECK: %8 = load i8*, i8** %saved_stack1, align 8
58+
// CHECK-NEXT: call void @llvm.stackrestore(i8* %8)
59+
60+
// CHECK: call void @llvm.directive.region.exit(token %3)
61+
62+
// CHECK: %9 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00") ]
63+
// CHECK-NEXT: %j = alloca i32, align 4
64+
// CHECK-NEXT: %k = alloca i32, align 4
65+
// CHECK-NEXT: %l = alloca i32, align 4
66+
// CHECK-NEXT: call void @llvm.directive.region.exit(token %9)
67+
68+
// CHECK: %10 = load i8*, i8** %saved_stack, align 8
69+
// CHECK-NEXT: call void @llvm.stackrestore(i8* %10)
70+

0 commit comments

Comments
 (0)