Skip to content

Commit 1394020

Browse files
committed
CodeGen: support oss depend clauses
closes llvm#18
1 parent 5d03613 commit 1394020

File tree

7 files changed

+528
-79
lines changed

7 files changed

+528
-79
lines changed

clang/lib/CodeGen/CGOmpSsRuntime.cpp

+268-24
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
#include "CGOmpSsRuntime.h"
1717
#include "CGRecordLayout.h"
1818
#include "CodeGenFunction.h"
19+
#include "ConstantEmitter.h"
1920
#include "clang/CodeGen/ConstantInitBuilder.h"
2021
#include "clang/AST/Decl.h"
2122
#include "clang/AST/StmtOmpSs.h"
23+
#include "clang/AST/StmtVisitor.h"
2224
#include "clang/Basic/BitmaskEnum.h"
2325
#include "llvm/ADT/ArrayRef.h"
2426
#include "llvm/Bitcode/BitcodeReader.h"
@@ -34,6 +36,251 @@
3436
using namespace clang;
3537
using namespace CodeGen;
3638

39+
class OSSDependVisitor
40+
: public ConstStmtVisitor<OSSDependVisitor, void> {
41+
CodeGenFunction &CGF;
42+
43+
llvm::Type *OSSArgTy;
44+
45+
llvm::Value *Ptr;
46+
SmallVector<llvm::Value *, 4> Starts;
47+
SmallVector<llvm::Value *, 4> Ends;
48+
SmallVector<llvm::Value *, 4> Dims;
49+
QualType BaseElementTy;
50+
51+
public:
52+
53+
OSSDependVisitor(CodeGenFunction &CGF)
54+
: CGF(CGF),
55+
OSSArgTy(CGF.ConvertType(CGF.getContext().LongTy))
56+
{}
57+
58+
//===--------------------------------------------------------------------===//
59+
// Utilities
60+
//===--------------------------------------------------------------------===//
61+
62+
void FillBaseExprDimsAndType(const Expr *E) {
63+
BaseElementTy = E->getType();
64+
if (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(BaseElementTy)){
65+
BaseElementTy = CGF.getContext().getBaseElementType(BaseElementTy);
66+
}
67+
QualType TmpTy = E->getType();
68+
// Add Dimensions
69+
if (TmpTy->isPointerType()) {
70+
// T *
71+
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, 1));
72+
} else if (!TmpTy->isArrayType()) {
73+
// T
74+
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, 1));
75+
}
76+
while (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(TmpTy)){
77+
// T []
78+
uint64_t DimSize = BaseArrayTy->getSize().getSExtValue();
79+
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, DimSize));
80+
TmpTy = BaseArrayTy->getElementType();
81+
}
82+
}
83+
84+
//===--------------------------------------------------------------------===//
85+
// Visitor Methods
86+
//===--------------------------------------------------------------------===//
87+
88+
void Visit(const Expr *E) {
89+
ConstStmtVisitor<OSSDependVisitor, void>::Visit(E);
90+
}
91+
92+
void VisitStmt(const Stmt *S) {
93+
llvm_unreachable("Unhandled stmt");
94+
}
95+
96+
void VisitExpr(const Expr *E) {
97+
llvm_unreachable("Unhandled expr");
98+
}
99+
100+
// l-values.
101+
void VisitDeclRefExpr(const DeclRefExpr *E) {
102+
Ptr = CGF.EmitDeclRefLValue(E).getPointer();
103+
FillBaseExprDimsAndType(E);
104+
}
105+
106+
void VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
107+
BaseElementTy = E->getType();
108+
// Get Base Type
109+
if (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(BaseElementTy)){
110+
BaseElementTy = CGF.getContext().getBaseElementType(BaseElementTy);
111+
}
112+
// Get the inner expr
113+
const Expr *Expr = E;
114+
while (const ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(Expr->IgnoreParenImpCasts())) {
115+
Expr = ASE->getBase();
116+
// Add indexes
117+
llvm::Value *Idx = ConstantEmitter(CGF).emitAbstract(ASE->getIdx(),
118+
ASE->getIdx()->getType());
119+
Idx = CGF.Builder.CreateSExt(Idx, OSSArgTy);
120+
llvm::Value *IdxEnd = CGF.Builder.CreateAdd(Idx, llvm::ConstantInt::getSigned(OSSArgTy, 1));
121+
Starts.push_back(Idx);
122+
Ends.push_back(IdxEnd);
123+
if (Expr->IgnoreParenImpCasts()->getType()->isPointerType())
124+
break;
125+
}
126+
127+
Ptr = CGF.EmitScalarExpr(Expr);
128+
129+
if (const CastExpr *CE = dyn_cast<CastExpr>(Expr)) {
130+
QualType TmpTy = CE->getType();
131+
// Add Dimensions
132+
if (TmpTy->isPointerType()) {
133+
// T (*)[]
134+
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, 1));
135+
TmpTy = cast<PointerType>(TmpTy)->getPointeeType();
136+
while (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(TmpTy)){
137+
// T []
138+
uint64_t DimSize = BaseArrayTy->getSize().getSExtValue();
139+
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, DimSize));
140+
TmpTy = BaseArrayTy->getElementType();
141+
}
142+
} else {
143+
// T *
144+
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, 1));
145+
}
146+
}
147+
}
148+
149+
void VisitMemberExpr(const MemberExpr *E) {
150+
Ptr = CGF.EmitMemberExpr(E).getPointer();
151+
FillBaseExprDimsAndType(E);
152+
}
153+
154+
void VisitUnaryDeref(const UnaryOperator *E) {
155+
Ptr = CGF.EmitUnaryOpLValue(E).getPointer();
156+
FillBaseExprDimsAndType(E);
157+
}
158+
159+
ArrayRef<llvm::Value *> getStarts() const {
160+
return Starts;
161+
}
162+
163+
ArrayRef<llvm::Value *> getEnds() const {
164+
return Ends;
165+
}
166+
167+
ArrayRef<llvm::Value *> getDims() const {
168+
return Dims;
169+
}
170+
171+
QualType getBaseElementTy() {
172+
return BaseElementTy;
173+
}
174+
175+
llvm::Value *getPtr() {
176+
return Ptr;
177+
}
178+
179+
};
180+
181+
static void EmitDSA(StringRef Name, CodeGenFunction &CGF, const Expr *E,
182+
SmallVectorImpl<llvm::OperandBundleDef> &TaskInfo) {
183+
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
184+
TaskInfo.emplace_back(Name, CGF.EmitDeclRefLValue(DRE).getPointer());
185+
}
186+
else {
187+
llvm_unreachable("Unhandled expression");
188+
}
189+
}
190+
191+
static void EmitDependency(StringRef Name, CodeGenFunction &CGF, const Expr *E,
192+
SmallVectorImpl<llvm::OperandBundleDef> &TaskInfo) {
193+
194+
// C long -> LLVM long
195+
llvm::Type *OSSArgTy = CGF.ConvertType(CGF.getContext().LongTy);
196+
197+
OSSDependVisitor DepVisitor(CGF);
198+
DepVisitor.Visit(E);
199+
200+
SmallVector<llvm::Value*, 4> DepData;
201+
202+
SmallVector<llvm::Value *, 4> Starts(
203+
DepVisitor.getStarts().begin(),
204+
DepVisitor.getStarts().end());
205+
206+
SmallVector<llvm::Value *, 4> Ends(
207+
DepVisitor.getEnds().begin(),
208+
DepVisitor.getEnds().end());
209+
210+
SmallVector<llvm::Value *, 4> Dims(
211+
DepVisitor.getDims().begin(),
212+
DepVisitor.getDims().end());
213+
QualType BaseElementTy = DepVisitor.getBaseElementTy();
214+
llvm::Value *Ptr = DepVisitor.getPtr();
215+
216+
uint64_t BaseElementSize =
217+
CGF.CGM
218+
.getDataLayout()
219+
.getTypeSizeInBits(CGF
220+
.ConvertType(BaseElementTy))/8;
221+
222+
DepData.push_back(Ptr);
223+
bool First = true;
224+
for (size_t i = Dims.size() - 1; i > 0; --i) {
225+
llvm::Value *Dim = Dims[i];
226+
llvm::Value *IdxStart;
227+
llvm::Value *IdxEnd;
228+
// In arrays we have to output all dimensions, but
229+
// the number of indices may be less than the number
230+
// of dimensions (array[1] -> int array[10][20])
231+
if (i < Starts.size()) {
232+
IdxStart = Starts[Starts.size() - i - 1];
233+
IdxEnd = Ends[Starts.size() - i - 1];
234+
} else {
235+
IdxStart = llvm::ConstantInt::getSigned(OSSArgTy, 0);
236+
IdxEnd = Dim;
237+
}
238+
if (First) {
239+
First = false;
240+
Dim = CGF.Builder.CreateMul(Dim,
241+
llvm::ConstantInt::getSigned(OSSArgTy,
242+
BaseElementSize));
243+
IdxStart = CGF.Builder.CreateMul(IdxStart,
244+
llvm::ConstantInt::getSigned(OSSArgTy,
245+
BaseElementSize));
246+
IdxEnd = CGF.Builder.CreateMul(IdxEnd,
247+
llvm::ConstantInt::getSigned(OSSArgTy,
248+
BaseElementSize));
249+
}
250+
DepData.push_back(Dim);
251+
DepData.push_back(IdxStart);
252+
DepData.push_back(IdxEnd);
253+
}
254+
llvm::Value *Dim = Dims[0];
255+
llvm::Value *IdxStart;
256+
llvm::Value *IdxEnd;
257+
if (Starts.size() > 0) {
258+
IdxStart = Starts[Starts.size() - 1];
259+
IdxEnd = Ends[Starts.size() - 1];
260+
} else {
261+
IdxStart = llvm::ConstantInt::getSigned(OSSArgTy, 0);
262+
IdxEnd = Dim;
263+
}
264+
265+
if (First) {
266+
First = false;
267+
Dim = CGF.Builder.CreateMul(Dim,
268+
llvm::ConstantInt::getSigned(OSSArgTy,
269+
BaseElementSize));
270+
IdxStart = CGF.Builder.CreateMul(IdxStart,
271+
llvm::ConstantInt::getSigned(OSSArgTy,
272+
BaseElementSize));
273+
IdxEnd = CGF.Builder.CreateMul(IdxEnd,
274+
llvm::ConstantInt::getSigned(OSSArgTy,
275+
BaseElementSize));
276+
}
277+
DepData.push_back(Dim);
278+
DepData.push_back(IdxStart);
279+
DepData.push_back(IdxEnd);
280+
281+
TaskInfo.emplace_back(Name, makeArrayRef(DepData));
282+
}
283+
37284
void CGOmpSsRuntime::emitTaskwaitCall(CodeGenFunction &CGF,
38285
SourceLocation Loc) {
39286
llvm::Value *Callee = CGM.getIntrinsic(llvm::Intrinsic::directive_marker);
@@ -53,34 +300,31 @@ void CGOmpSsRuntime::emitTaskCall(CodeGenFunction &CGF,
53300
SmallVector<llvm::OperandBundleDef, 8> TaskInfo;
54301
TaskInfo.emplace_back("DIR.OSS", llvm::ConstantDataArray::getString(CGM.getLLVMContext(), "TASK"));
55302
for (const Expr *E : Data.SharedVars) {
56-
const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
57-
if (VD->hasLocalStorage()) {
58-
Address Addr = CGF.GetAddrOfLocalVar(VD);
59-
TaskInfo.emplace_back("QUAL.OSS.SHARED", Addr.getPointer());
60-
}
61-
else {
62-
TaskInfo.emplace_back("QUAL.OSS.SHARED", CGM.GetAddrOfGlobalVar(VD));
63-
}
303+
EmitDSA("QUAL.OSS.SHARED", CGF, E, TaskInfo);
64304
}
65305
for (const Expr *E : Data.PrivateVars) {
66-
const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
67-
if (VD->hasLocalStorage()) {
68-
Address Addr = CGF.GetAddrOfLocalVar(VD);
69-
TaskInfo.emplace_back("QUAL.OSS.PRIVATE", Addr.getPointer());
70-
}
71-
else {
72-
TaskInfo.emplace_back("QUAL.OSS.PRIVATE", CGM.GetAddrOfGlobalVar(VD));
73-
}
306+
EmitDSA("QUAL.OSS.PRIVATE", CGF, E, TaskInfo);
74307
}
75308
for (const Expr *E : Data.FirstprivateVars) {
76-
const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
77-
if (VD->hasLocalStorage()) {
78-
Address Addr = CGF.GetAddrOfLocalVar(VD);
79-
TaskInfo.emplace_back("QUAL.OSS.FIRSTPRIVATE", Addr.getPointer());
80-
}
81-
else {
82-
TaskInfo.emplace_back("QUAL.OSS.FIRSTPRIVATE", CGM.GetAddrOfGlobalVar(VD));
83-
}
309+
EmitDSA("QUAL.OSS.FIRSTPRIVATE", CGF, E, TaskInfo);
310+
}
311+
for (const Expr *E : Data.DependIn) {
312+
EmitDependency("QUAL.OSS.DEP.IN", CGF, E, TaskInfo);
313+
}
314+
for (const Expr *E : Data.DependOut) {
315+
EmitDependency("QUAL.OSS.DEP.OUT", CGF, E, TaskInfo);
316+
}
317+
for (const Expr *E : Data.DependInout) {
318+
EmitDependency("QUAL.OSS.DEP.INOUT", CGF, E, TaskInfo);
319+
}
320+
for (const Expr *E : Data.DependWeakIn) {
321+
EmitDependency("QUAL.OSS.DEP.WEAKIN", CGF, E, TaskInfo);
322+
}
323+
for (const Expr *E : Data.DependWeakOut) {
324+
EmitDependency("QUAL.OSS.DEP.WEAKOUT", CGF, E, TaskInfo);
325+
}
326+
for (const Expr *E : Data.DependWeakInout) {
327+
EmitDependency("QUAL.OSS.DEP.WEAKINOUT", CGF, E, TaskInfo);
84328
}
85329

86330
llvm::Value *Result =

clang/lib/CodeGen/CGOmpSsRuntime.h

+6
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ struct OSSTaskDataTy final {
3636
SmallVector<const Expr *, 4> SharedVars;
3737
SmallVector<const Expr *, 4> PrivateVars;
3838
SmallVector<const Expr *, 4> FirstprivateVars;
39+
SmallVector<const Expr *, 4> DependWeakIn;
40+
SmallVector<const Expr *, 4> DependWeakOut;
41+
SmallVector<const Expr *, 4> DependWeakInout;
42+
SmallVector<const Expr *, 4> DependIn;
43+
SmallVector<const Expr *, 4> DependOut;
44+
SmallVector<const Expr *, 4> DependInout;
3945
};
4046

4147
class CGOmpSsRuntime {

clang/lib/CodeGen/CGStmtOmpSs.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,32 @@ void CodeGenFunction::EmitOSSTaskDirective(const OSSTaskDirective &S) {
4040
for (const Expr *Ref : C->varlists())
4141
Data.FirstprivateVars.push_back(Ref);
4242
}
43+
for (const auto *C : S.getClausesOfKind<OSSDependClause>()) {
44+
ArrayRef<OmpSsDependClauseKind> DepKinds = C->getDependencyKind();
45+
if (DepKinds.size() == 2) {
46+
for (const Expr *Ref : C->varlists()) {
47+
if (DepKinds[0] == OSSC_DEPEND_in
48+
|| DepKinds[1] == OSSC_DEPEND_in)
49+
Data.DependWeakIn.push_back(Ref);
50+
if (DepKinds[0] == OSSC_DEPEND_out
51+
|| DepKinds[1] == OSSC_DEPEND_out)
52+
Data.DependWeakOut.push_back(Ref);
53+
if (DepKinds[0] == OSSC_DEPEND_inout
54+
|| DepKinds[1] == OSSC_DEPEND_inout)
55+
Data.DependWeakInout.push_back(Ref);
56+
}
57+
}
58+
else {
59+
for (const Expr *Ref : C->varlists()) {
60+
if (DepKinds[0] == OSSC_DEPEND_in)
61+
Data.DependIn.push_back(Ref);
62+
if (DepKinds[0] == OSSC_DEPEND_out)
63+
Data.DependOut.push_back(Ref);
64+
if (DepKinds[0] == OSSC_DEPEND_inout)
65+
Data.DependInout.push_back(Ref);
66+
}
67+
}
68+
}
4369

4470
CGM.getOmpSsRuntime().emitTaskCall(*this, S, S.getBeginLoc(), Data);
4571
}

0 commit comments

Comments
 (0)