Home | History | Annotate | Download | only in CodeGen
      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(*CS);
     36   }
     37 
     38   // Build call __kmpc_fork_call(loc, 1, microtask, captured_struct/*context*/)
     39   llvm::Value *Args[] = {
     40       CGM.getOpenMPRuntime().EmitOpenMPUpdateLocation(*this, S.getLocStart()),
     41       Builder.getInt32(1), // Number of arguments after 'microtask' argument
     42       // (there is only one additional argument - 'context')
     43       Builder.CreateBitCast(OutlinedFn,
     44                             CGM.getOpenMPRuntime().getKmpc_MicroPointerTy()),
     45       EmitCastToVoidPtr(CapturedStruct)};
     46   llvm::Constant *RTLFn = CGM.getOpenMPRuntime().CreateRuntimeFunction(
     47       CGOpenMPRuntime::OMPRTL__kmpc_fork_call);
     48   EmitRuntimeCall(RTLFn, Args);
     49 }
     50 
     51 void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
     52   const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt());
     53   const Stmt *Body = CS->getCapturedStmt();
     54   LoopStack.setParallel();
     55   LoopStack.setVectorizerEnable(true);
     56   for (auto C : S.clauses()) {
     57     switch (C->getClauseKind()) {
     58     case OMPC_safelen: {
     59       RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(),
     60                                AggValueSlot::ignored(), true);
     61       llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
     62       LoopStack.setVectorizerWidth(Val->getZExtValue());
     63       // In presence of finite 'safelen', it may be unsafe to mark all
     64       // the memory instructions parallel, because loop-carried
     65       // dependences of 'safelen' iterations are possible.
     66       LoopStack.setParallel(false);
     67       break;
     68     }
     69     default:
     70       // Not handled yet
     71       ;
     72     }
     73   }
     74   EmitStmt(Body);
     75 }
     76 
     77 void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &) {
     78   llvm_unreachable("CodeGen for 'omp for' is not supported yet.");
     79 }
     80 
     81 void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &) {
     82   llvm_unreachable("CodeGen for 'omp sections' is not supported yet.");
     83 }
     84 
     85 void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &) {
     86   llvm_unreachable("CodeGen for 'omp section' is not supported yet.");
     87 }
     88 
     89 void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &) {
     90   llvm_unreachable("CodeGen for 'omp single' is not supported yet.");
     91 }
     92 
     93 void
     94 CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) {
     95   llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet.");
     96 }
     97 
     98 void CodeGenFunction::EmitOMPParallelSectionsDirective(
     99     const OMPParallelSectionsDirective &) {
    100   llvm_unreachable("CodeGen for 'omp parallel sections' is not supported yet.");
    101 }
    102 
    103