Skip to content

Commit

Permalink
[OPENMP51]Codegen for error directive.
Browse files Browse the repository at this point in the history
Added codegen for `omp error` directive.
This is to generate IR to call:
void __kmpc_error(ident_t *loc, int severity, const char *message);

Differential Revision: https://reviews.llvm.org/D139166
  • Loading branch information
jyu2-git committed Dec 8, 2022
1 parent 3cfaea2 commit af781f7
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 4 deletions.
21 changes: 19 additions & 2 deletions clang/lib/CodeGen/CGOpenMPRuntime.cpp
Expand Up @@ -1363,10 +1363,11 @@ static StringRef getIdentStringFromSourceLocation(CodeGenFunction &CGF,

llvm::Value *CGOpenMPRuntime::emitUpdateLocation(CodeGenFunction &CGF,
SourceLocation Loc,
unsigned Flags) {
unsigned Flags, bool EmitLoc) {
uint32_t SrcLocStrSize;
llvm::Constant *SrcLocStr;
if (CGM.getCodeGenOpts().getDebugInfo() == codegenoptions::NoDebugInfo ||
if ((!EmitLoc &&
CGM.getCodeGenOpts().getDebugInfo() == codegenoptions::NoDebugInfo) ||
Loc.isInvalid()) {
SrcLocStr = OMPBuilder.getOrCreateDefaultSrcLocStr(SrcLocStrSize);
} else {
Expand Down Expand Up @@ -2557,6 +2558,22 @@ void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
Args);
}

void CGOpenMPRuntime::emitErrorCall(CodeGenFunction &CGF, SourceLocation Loc,
Expr *ME, bool IsFatal) {
llvm::Value *MVL =
ME ? CGF.EmitStringLiteralLValue(cast<StringLiteral>(ME)).getPointer(CGF)
: llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
// Build call void __kmpc_error(ident_t *loc, int severity, const char
// *message)
llvm::Value *Args[] = {
emitUpdateLocation(CGF, Loc, /*Flags=*/0, /*GenLoc=*/true),
llvm::ConstantInt::get(CGM.Int32Ty, IsFatal ? 2 : 1),
CGF.Builder.CreatePointerCast(MVL, CGM.Int8PtrTy)};
CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
CGM.getModule(), OMPRTL___kmpc_error),
Args);
}

/// Map the OpenMP loop schedule to the runtime enumeration.
static OpenMPSchedType getRuntimeSchedule(OpenMPScheduleClauseKind ScheduleKind,
bool Chunked, bool Ordered) {
Expand Down
8 changes: 7 additions & 1 deletion clang/lib/CodeGen/CGOpenMPRuntime.h
Expand Up @@ -329,9 +329,10 @@ class CGOpenMPRuntime {

/// Emits object of ident_t type with info for source location.
/// \param Flags Flags for OpenMP location.
/// \param EmitLoc emit source location with debug-info is off.
///
llvm::Value *emitUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc,
unsigned Flags = 0);
unsigned Flags = 0, bool EmitLoc = false);

/// Emit the number of teams for a target directive. Inspect the num_teams
/// clause associated with a teams construct combined or closely nested
Expand Down Expand Up @@ -822,6 +823,11 @@ class CGOpenMPRuntime {
/// Emits code for a taskyield directive.
virtual void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc);

/// Emit __kmpc_error call for error directive
/// extern void __kmpc_error(ident_t *loc, int severity, const char *message);
virtual void emitErrorCall(CodeGenFunction &CGF, SourceLocation Loc, Expr *ME,
bool IsFatal);

/// Emit a taskgroup region.
/// \param TaskgroupOpGen Generator for the statement associated with the
/// given taskgroup region.
Expand Down
8 changes: 7 additions & 1 deletion clang/lib/CodeGen/CGStmtOpenMP.cpp
Expand Up @@ -5246,7 +5246,13 @@ void CodeGenFunction::EmitOMPTaskyieldDirective(
}

void CodeGenFunction::EmitOMPErrorDirective(const OMPErrorDirective &S) {
llvm_unreachable("CodeGen for 'omp error' is not supported yet.");
const OMPMessageClause *MC = S.getSingleClause<OMPMessageClause>();
Expr *ME = MC ? MC->getMessageString() : nullptr;
const OMPSeverityClause *SC = S.getSingleClause<OMPSeverityClause>();
bool IsFatal = false;
if (!SC || SC->getSeverityKind() == OMPC_SEVERITY_fatal)
IsFatal = true;
CGM.getOpenMPRuntime().emitErrorCall(*this, S.getBeginLoc(), ME, IsFatal);
}

void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) {
Expand Down
67 changes: 67 additions & 0 deletions clang/test/OpenMP/error_codegen.cpp
@@ -0,0 +1,67 @@
// RUN: %clang_cc1 -std=c++11 -fopenmp -fopenmp-version=51 -triple x86_64 \
// RUN: -emit-llvm -o - %s | FileCheck %s

// RUN: %clang_cc1 -std=c++11 -fopenmp-simd -fopenmp-version=51 \
// RUN: -debug-info-kind=limited -triple x86_64 -emit-llvm -o - %s | \
// RUN: FileCheck --check-prefix SIMD %s

//CHECK: @.str = private unnamed_addr constant [23 x i8] c"GPU compiler required.\00", align 1
//CHECK: @0 = private unnamed_addr constant {{.*}}error_codegen.cpp;main;52;1;;\00", align 1
//CHECK: @1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 {{.*}}, ptr @0 }, align 8
//CHECK: @.str.1 = private unnamed_addr constant [27 x i8] c"Note this is functioncall.\00", align 1
//CHECK: @2 = private unnamed_addr constant {{.*}}error_codegen.cpp;main;54;1;;\00", align 1
//CHECK: @3 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 {{.*}}, ptr @2 }, align 8
//CHECK: @.str.2 = private unnamed_addr constant [23 x i8] c"GNU compiler required.\00", align 1
//CHECK: @4 = private unnamed_addr constant {{.*}}error_codegen.cpp;tmain;29;1;;\00", align 1
//CHECK: @5 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 {{.*}}, ptr @4 }, align 8
//CHECK: @.str.3 = private unnamed_addr constant [22 x i8] c"Notice: add for loop.\00", align 1
//CHECK: @6 = private unnamed_addr constant {{.*}}error_codegen.cpp;tmain;32;1;;\00", align 1
//CHECK: @7 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 {{.*}}, ptr @6 }, align 8
//CHECK: @8 = private unnamed_addr constant {{.*}}error_codegen.cpp;tmain;38;1;;\00", align 1
//CHECK: @9 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 {{.*}}, ptr @8 }, align 8

void foo() {}

template <typename T, int N>
int tmain(T argc, char **argv) {
T b = argc, c, d, e, f, g;
static int a;
#pragma omp error at(execution) severity(fatal) message("GNU compiler required.")
a = argv[0][0];
++a;
#pragma omp error at(execution) severity(warning) message("Notice: add for loop.")
{
int b = 10;
T c = 100;
a = b + c;
}
#pragma omp error at(execution) severity(fatal) message("GPU compiler required.")
foo();
return N;
}
// CHECK-LABEL: @main(
// SIMD-LABEL: @main(
// CHECK: call void @__kmpc_error(ptr @1, i32 2, ptr @.str)
// SIMD-NOT: call void @__kmpc_error(ptr @1, i32 2, ptr @.str)
// CHECK: call void @__kmpc_error(ptr @3, i32 1, ptr @.str.1)
// SIMD-NOT: call void @__kmpc_error(ptr @3, i32 1, ptr @.str.1)
//
int main (int argc, char **argv) {
int b = argc, c, d, e, f, g;
static int a;
#pragma omp error at(execution) severity(fatal) message("GPU compiler required.")
a=2;
#pragma omp error at(execution) severity(warning) message("Note this is functioncall.")
foo();
tmain<int, 10>(argc, argv);
}

//CHECK-LABEL: @_Z5tmainIiLi10EEiT_PPc(
//SIMD-LABEL: @_Z5tmainIiLi10EEiT_PPc(
//CHECK: call void @__kmpc_error(ptr @5, i32 2, ptr @.str.2)
//CHECK: call void @__kmpc_error(ptr @7, i32 1, ptr @.str.3)
//CHECK: call void @__kmpc_error(ptr @9, i32 2, ptr @.str)
//SIMD-NOT: call void @__kmpc_error(ptr @5, i32 2, ptr @.str.2)
//SIMD-NOT: call void @__kmpc_error(ptr @7, i32 1, ptr @.str.3)
//SIMD-NOT: call void @__kmpc_error(ptr @9, i32 2, ptr @.str)
//CHECK: ret i32 10
1 change: 1 addition & 0 deletions llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
Expand Up @@ -198,6 +198,7 @@ __ICV_RT_GET(proc_bind, omp_get_proc_bind)
__OMP_RTL(__kmpc_barrier, false, Void, IdentPtr, Int32)
__OMP_RTL(__kmpc_cancel, false, Int32, IdentPtr, Int32, Int32)
__OMP_RTL(__kmpc_cancel_barrier, false, Int32, IdentPtr, Int32)
__OMP_RTL(__kmpc_error, false, Void, IdentPtr, Int32, Int8Ptr)
__OMP_RTL(__kmpc_flush, false, Void, IdentPtr)
__OMP_RTL(__kmpc_global_thread_num, false, Int32, IdentPtr)
__OMP_RTL(__kmpc_get_hardware_thread_id_in_block, false, Int32, )
Expand Down

0 comments on commit af781f7

Please sign in to comment.