1 //===--- 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" 19 using namespace clang; 20 using namespace CodeGen; 21 22 //===----------------------------------------------------------------------===// 23 // OpenMP Directive Emission 24 //===----------------------------------------------------------------------===// 25 26 void 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 llvm::Constant *RTLFn = CGM.getOpenMPRuntime().CreateRuntimeFunction( 48 CGOpenMPRuntime::OMPRTL__kmpc_fork_call); 49 EmitRuntimeCall(RTLFn, Args); 50 } 51 52 void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { 53 const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt()); 54 const Stmt *Body = CS->getCapturedStmt(); 55 LoopStack.setParallel(); 56 LoopStack.setVectorizerEnable(true); 57 for (auto C : S.clauses()) { 58 switch (C->getClauseKind()) { 59 case OMPC_safelen: { 60 RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(), 61 AggValueSlot::ignored(), true); 62 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal()); 63 LoopStack.setVectorizerWidth(Val->getZExtValue()); 64 // In presence of finite 'safelen', it may be unsafe to mark all 65 // the memory instructions parallel, because loop-carried 66 // dependences of 'safelen' iterations are possible. 67 LoopStack.setParallel(false); 68 break; 69 } 70 default: 71 // Not handled yet 72 ; 73 } 74 } 75 EmitStmt(Body); 76 } 77 78 void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &) { 79 llvm_unreachable("Not supported yet."); 80 } 81