blob: 9f915fa2d3758ed54e1a0e10b1b0400a8f729d09 [file] [log] [blame]
Alexey Bataev9959db52014-05-06 10:08:46 +00001//===--- CGStmtOpenMP.cpp - Emit LLVM Code from Statements ----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This contains code to emit OpenMP nodes as LLVM code.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CGOpenMPRuntime.h"
15#include "CodeGenFunction.h"
16#include "CodeGenModule.h"
17#include "clang/AST/Stmt.h"
18#include "clang/AST/StmtOpenMP.h"
19using namespace clang;
20using namespace CodeGen;
21
22//===----------------------------------------------------------------------===//
23// OpenMP Directive Emission
24//===----------------------------------------------------------------------===//
25
26void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
27 const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt());
28 llvm::Value *CapturedStruct = GenerateCapturedStmtArgument(*CS);
29
30 llvm::Value *OutlinedFn;
31 {
32 CodeGenFunction CGF(CGM, true);
33 CGCapturedStmtInfo CGInfo(*CS, CS->getCapturedRegionKind());
34 CGF.CapturedStmtInfo = &CGInfo;
35 OutlinedFn = CGF.GenerateCapturedStmtFunction(
36 CS->getCapturedDecl(), CS->getCapturedRecordDecl(), CS->getLocStart());
37 }
38
39 // Build call __kmpc_fork_call(loc, 1, microtask, captured_struct/*context*/)
40 llvm::Value *Args[] = {
41 CGM.getOpenMPRuntime().EmitOpenMPUpdateLocation(*this, S.getLocStart()),
42 Builder.getInt32(1), // Number of arguments after 'microtask' argument
43 // (there is only one additional argument - 'context')
44 Builder.CreateBitCast(OutlinedFn,
45 CGM.getOpenMPRuntime().getKmpc_MicroPointerTy()),
46 EmitCastToVoidPtr(CapturedStruct)
47 };
48 llvm::Constant *RTLFn = CGM.getOpenMPRuntime().CreateRuntimeFunction(
49 CGOpenMPRuntime::OMPRTL__kmpc_fork_call);
50 EmitRuntimeCall(RTLFn, Args);
51}
Alexander Musman515ad8c2014-05-22 08:54:05 +000052
53void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
54 const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt());
55 const Stmt *Body = CS->getCapturedStmt();
56 LoopStack.setParallel();
57 LoopStack.setVectorizerEnable(true);
58 for (auto C : S.clauses()) {
59 switch (C->getClauseKind()) {
60 case OMPC_safelen: {
61 RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(),
62 AggValueSlot::ignored(), true);
63 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
64 LoopStack.setVectorizerWidth(Val->getZExtValue());
65 // In presence of finite 'safelen', it may be unsafe to mark all
66 // the memory instructions parallel, because loop-carried
67 // dependences of 'safelen' iterations are possible.
68 LoopStack.setParallel(false);
69 break;
70 }
71 default:
72 // Not handled yet
73 ;
74 }
75 }
76 EmitStmt(Body);
77}
78
Alexey Bataevf29276e2014-06-18 04:14:57 +000079void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &) {
80 llvm_unreachable("Not supported yet.");
81}