27 changes: 27 additions & 0 deletions clang/lib/CodeGen/CGStmtOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,30 @@ void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
CGOpenMPRuntime::OMPRTL__kmpc_fork_call);
EmitRuntimeCall(RTLFn, Args);
}

void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt());
const Stmt *Body = CS->getCapturedStmt();
LoopStack.setParallel();
LoopStack.setVectorizerEnable(true);
for (auto C : S.clauses()) {
switch (C->getClauseKind()) {
case OMPC_safelen: {
RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(),
AggValueSlot::ignored(), true);
llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
LoopStack.setVectorizerWidth(Val->getZExtValue());
// In presence of finite 'safelen', it may be unsafe to mark all
// the memory instructions parallel, because loop-carried
// dependences of 'safelen' iterations are possible.
LoopStack.setParallel(false);
break;
}
default:
// Not handled yet
;
}
}
EmitStmt(Body);
}

1 change: 1 addition & 0 deletions clang/lib/CodeGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ add_clang_library(clangCodeGen
CGExprComplex.cpp
CGExprConstant.cpp
CGExprScalar.cpp
CGLoopInfo.cpp
CGObjC.cpp
CGObjCGNU.cpp
CGObjCMac.cpp
Expand Down
30 changes: 29 additions & 1 deletion clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ using namespace CodeGen;

CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
: CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()),
Builder(cgm.getModule().getContext()), CapturedStmtInfo(nullptr),
Builder(cgm.getModule().getContext(), llvm::ConstantFolder(),
CGBuilderInserterTy(this)), CapturedStmtInfo(nullptr),
SanitizePerformTypeCheck(CGM.getSanOpts().Null |
CGM.getSanOpts().Alignment |
CGM.getSanOpts().ObjectSize |
Expand Down Expand Up @@ -1644,3 +1645,30 @@ llvm::Value *CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D,
}

CodeGenFunction::CGCapturedStmtInfo::~CGCapturedStmtInfo() { }

void CodeGenFunction::InsertHelper(llvm::Instruction *I,
const llvm::Twine &Name,
llvm::BasicBlock *BB,
llvm::BasicBlock::iterator InsertPt) const {
LoopStack.InsertHelper(I);
}

template <bool PreserveNames>
void CGBuilderInserter<PreserveNames>::InsertHelper(
llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock *BB,
llvm::BasicBlock::iterator InsertPt) const {
llvm::IRBuilderDefaultInserter<PreserveNames>::InsertHelper(I, Name, BB,
InsertPt);
if (CGF)
CGF->InsertHelper(I, Name, BB, InsertPt);
}

#ifdef NDEBUG
#define PreserveNames false
#else
#define PreserveNames true
#endif
template void CGBuilderInserter<PreserveNames>::InsertHelper(
llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock *BB,
llvm::BasicBlock::iterator InsertPt) const;
#undef PreserveNames
9 changes: 9 additions & 0 deletions clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "CGBuilder.h"
#include "CGDebugInfo.h"
#include "CGLoopInfo.h"
#include "CGValue.h"
#include "CodeGenModule.h"
#include "CodeGenPGO.h"
Expand Down Expand Up @@ -129,8 +130,15 @@ class CodeGenFunction : public CodeGenTypeCache {
const TargetInfo &Target;

typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy;
LoopInfoStack LoopStack;
CGBuilderTy Builder;

/// \brief CGBuilder insert helper. This function is called after an
/// instruction is created using Builder.
void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
llvm::BasicBlock *BB,
llvm::BasicBlock::iterator InsertPt) const;

/// CurFuncDecl - Holds the Decl for the current outermost
/// non-closure context.
const Decl *CurFuncDecl;
Expand Down Expand Up @@ -1883,6 +1891,7 @@ class CodeGenFunction : public CodeGenTypeCache {
llvm::Value *GenerateCapturedStmtArgument(const CapturedStmt &S);

void EmitOMPParallelDirective(const OMPParallelDirective &S);
void EmitOMPSimdDirective(const OMPSimdDirective &S);

//===--------------------------------------------------------------------===//
// LValue Expression Emission
Expand Down
52 changes: 52 additions & 0 deletions clang/test/OpenMP/simd_metadata.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// RUN: %clang_cc1 -fopenmp=libiomp5 -emit-llvm %s -o - | FileCheck %s

void h1(float *c, float *a, float *b, int size)
{
// CHECK-LABEL: define void @h1
int t = 0;
#pragma omp simd safelen(16) linear(t)
for (int i = 0; i < size; ++i) {
c[i] = a[i] * a[i] + b[i] * b[t];
++t;
// do not emit parallel_loop_access metadata due to usage of safelen clause.
// CHECK-NOT: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.mem.parallel_loop_access {{![0-9]+}}
}
}

void h2(float *c, float *a, float *b, int size)
{
// CHECK-LABEL: define void @h2
int t = 0;
#pragma omp simd linear(t)
for (int i = 0; i < size; ++i) {
c[i] = a[i] * a[i] + b[i] * b[t];
++t;
// CHECK: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.mem.parallel_loop_access [[LOOP_H2_HEADER:![0-9]+]]
}
}

void h3(float *c, float *a, float *b, int size)
{
// CHECK-LABEL: define void @h3
#pragma omp simd
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
c[j*i] = a[i] * b[j];
}
}
// do not emit parallel_loop_access for nested loop.
// CHECK-NOT: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.mem.parallel_loop_access {{![0-9]+}}
}

// Metadata for h1:
// CHECK: [[LOOP_H1_HEADER:![0-9]+]] = metadata !{metadata [[LOOP_H1_HEADER]], metadata [[LOOP_WIDTH_16:![0-9]+]], metadata [[LOOP_VEC_ENABLE:![0-9]+]]}
// CHECK: [[LOOP_WIDTH_16]] = metadata !{metadata !"llvm.vectorizer.width", i32 16}
// CHECK: [[LOOP_VEC_ENABLE]] = metadata !{metadata !"llvm.vectorizer.enable", i1 true}
//
// Metadata for h2:
// CHECK: [[LOOP_H2_HEADER]] = metadata !{metadata [[LOOP_H2_HEADER]], metadata [[LOOP_VEC_ENABLE]]}
//
// Metadata for h3:
// CHECK: [[LOOP_H3_HEADER:![0-9]+]] = metadata !{metadata [[LOOP_H3_HEADER]], metadata [[LOOP_VEC_ENABLE]]}
//