16bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//===----- CGOpenMPRuntime.cpp - Interface to OpenMP Runtimes -------------===//
26bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//
36bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//                     The LLVM Compiler Infrastructure
46bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//
56bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// This file is distributed under the University of Illinois Open Source
66bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// License. See LICENSE.TXT for details.
76bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//
86bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//===----------------------------------------------------------------------===//
96bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//
106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// This provides a class for OpenMP runtime code generation.
116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//
126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//===----------------------------------------------------------------------===//
136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "CGOpenMPRuntime.h"
156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "CodeGenFunction.h"
166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "clang/AST/Decl.h"
176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/ADT/ArrayRef.h"
186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/IR/DerivedTypes.h"
196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/IR/GlobalValue.h"
206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/IR/Value.h"
216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/Support/raw_ostream.h"
22ef8225444452a1486bd721f3285301fe84643b00Stephen Hines#include <cassert>
236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesusing namespace clang;
256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesusing namespace CodeGen;
266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesCGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM)
286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    : CGM(CGM), DefaultOpenMPPSource(nullptr) {
296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  IdentTy = llvm::StructType::create(
306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      "ident_t", CGM.Int32Ty /* reserved_1 */, CGM.Int32Ty /* flags */,
316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      CGM.Int32Ty /* reserved_2 */, CGM.Int32Ty /* reserved_3 */,
326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      CGM.Int8PtrTy /* psource */, NULL);
336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // Build void (*kmpc_micro)(kmp_int32 *global_tid, kmp_int32 *bound_tid,...)
34ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  llvm::Type *MicroParams[] = {llvm::PointerType::getUnqual(CGM.Int32Ty),
35ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                               llvm::PointerType::getUnqual(CGM.Int32Ty)};
366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Kmpc_MicroTy = llvm::FunctionType::get(CGM.VoidTy, MicroParams, true);
376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesllvm::Value *
406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesCGOpenMPRuntime::GetOrCreateDefaultOpenMPLocation(OpenMPLocationFlags Flags) {
416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  llvm::Value *Entry = OpenMPDefaultLocMap.lookup(Flags);
426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!Entry) {
436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (!DefaultOpenMPPSource) {
446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      // Initialize default location for psource field of ident_t structure of
456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      // all ident_t objects. Format is ";file;function;line;column;;".
466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      // Taken from
476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      // http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp_str.c
486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      DefaultOpenMPPSource =
496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          CGM.GetAddrOfConstantCString(";unknown;unknown;0;0;;");
506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      DefaultOpenMPPSource =
516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource, CGM.Int8PtrTy);
526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    }
536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    llvm::GlobalVariable *DefaultOpenMPLocation = cast<llvm::GlobalVariable>(
546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        CGM.CreateRuntimeVariable(IdentTy, ".kmpc_default_loc.addr"));
556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    DefaultOpenMPLocation->setUnnamedAddr(true);
566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    DefaultOpenMPLocation->setConstant(true);
576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    DefaultOpenMPLocation->setLinkage(llvm::GlobalValue::PrivateLinkage);
586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    llvm::Constant *Zero = llvm::ConstantInt::get(CGM.Int32Ty, 0, true);
60ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    llvm::Constant *Values[] = {Zero,
61ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                llvm::ConstantInt::get(CGM.Int32Ty, Flags),
62ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                Zero, Zero, DefaultOpenMPPSource};
636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    llvm::Constant *Init = llvm::ConstantStruct::get(IdentTy, Values);
646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    DefaultOpenMPLocation->setInitializer(Init);
656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return DefaultOpenMPLocation;
666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return Entry;
686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesllvm::Value *CGOpenMPRuntime::EmitOpenMPUpdateLocation(
716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    CodeGenFunction &CGF, SourceLocation Loc, OpenMPLocationFlags Flags) {
726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // If no debug info is generated - return global default location.
736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (CGM.getCodeGenOpts().getDebugInfo() == CodeGenOptions::NoDebugInfo ||
746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      Loc.isInvalid())
756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return GetOrCreateDefaultOpenMPLocation(Flags);
766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  assert(CGF.CurFn && "No function in current CodeGenFunction.");
786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  llvm::Value *LocValue = nullptr;
806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  OpenMPLocMapTy::iterator I = OpenMPLocMap.find(CGF.CurFn);
816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (I != OpenMPLocMap.end()) {
826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    LocValue = I->second;
836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  } else {
846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Generate "ident_t .kmpc_loc.addr;"
856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    llvm::AllocaInst *AI = CGF.CreateTempAlloca(IdentTy, ".kmpc_loc.addr");
866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AI->setAlignment(CGM.getDataLayout().getPrefTypeAlignment(IdentTy));
876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    OpenMPLocMap[CGF.CurFn] = AI;
886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    LocValue = AI;
896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt);
926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    CGF.Builder.CreateMemCpy(LocValue, GetOrCreateDefaultOpenMPLocation(Flags),
936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                             llvm::ConstantExpr::getSizeOf(IdentTy),
946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                             CGM.PointerAlignInBytes);
956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // char **psource = &.kmpc_loc_<flags>.addr.psource;
986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  llvm::Value *PSource =
996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      CGF.Builder.CreateConstInBoundsGEP2_32(LocValue, 0, IdentField_PSource);
1006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
101ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  auto OMPDebugLoc = OpenMPDebugLocMap.lookup(Loc.getRawEncoding());
102ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (OMPDebugLoc == nullptr) {
103ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    SmallString<128> Buffer2;
104ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    llvm::raw_svector_ostream OS2(Buffer2);
105ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    // Build debug location
106ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc);
107ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    OS2 << ";" << PLoc.getFilename() << ";";
108ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    if (const FunctionDecl *FD =
109ef8225444452a1486bd721f3285301fe84643b00Stephen Hines            dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl)) {
110ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      OS2 << FD->getQualifiedNameAsString();
111ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    }
112ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    OS2 << ";" << PLoc.getLine() << ";" << PLoc.getColumn() << ";;";
113ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    OMPDebugLoc = CGF.Builder.CreateGlobalStringPtr(OS2.str());
114ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    OpenMPDebugLocMap[Loc.getRawEncoding()] = OMPDebugLoc;
1156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // *psource = ";<File>;<Function>;<Line>;<Column>;;";
117ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  CGF.Builder.CreateStore(OMPDebugLoc, PSource);
118ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
1196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return LocValue;
1206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
1216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesllvm::Value *CGOpenMPRuntime::GetOpenMPGlobalThreadNum(CodeGenFunction &CGF,
1236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                                       SourceLocation Loc) {
1246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  assert(CGF.CurFn && "No function in current CodeGenFunction.");
1256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  llvm::Value *GTid = nullptr;
1276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  OpenMPGtidMapTy::iterator I = OpenMPGtidMap.find(CGF.CurFn);
1286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (I != OpenMPGtidMap.end()) {
1296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    GTid = I->second;
1306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  } else {
1316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Generate "int32 .kmpc_global_thread_num.addr;"
1326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
1336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt);
134ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    llvm::Value *Args[] = {EmitOpenMPUpdateLocation(CGF, Loc)};
1356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    GTid = CGF.EmitRuntimeCall(
1366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        CreateRuntimeFunction(OMPRTL__kmpc_global_thread_num), Args);
1376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    OpenMPGtidMap[CGF.CurFn] = GTid;
1386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return GTid;
1406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
1416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid CGOpenMPRuntime::FunctionFinished(CodeGenFunction &CGF) {
1436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  assert(CGF.CurFn && "No function in current CodeGenFunction.");
1446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (OpenMPGtidMap.count(CGF.CurFn))
1456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    OpenMPGtidMap.erase(CGF.CurFn);
1466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (OpenMPLocMap.count(CGF.CurFn))
1476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    OpenMPLocMap.erase(CGF.CurFn);
1486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
1496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesllvm::Type *CGOpenMPRuntime::getIdentTyPointerTy() {
1516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return llvm::PointerType::getUnqual(IdentTy);
1526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
1536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesllvm::Type *CGOpenMPRuntime::getKmpc_MicroPointerTy() {
1556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return llvm::PointerType::getUnqual(Kmpc_MicroTy);
1566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
1576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesllvm::Constant *
1596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesCGOpenMPRuntime::CreateRuntimeFunction(OpenMPRTLFunction Function) {
1606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  llvm::Constant *RTLFn = nullptr;
1616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  switch (Function) {
1626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  case OMPRTL__kmpc_fork_call: {
1636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Build void __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro
1646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // microtask, ...);
165ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
166ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                getKmpc_MicroPointerTy()};
1676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    llvm::FunctionType *FnTy =
1686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        llvm::FunctionType::get(CGM.VoidTy, TypeParams, true);
1696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_fork_call");
1706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    break;
1716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  case OMPRTL__kmpc_global_thread_num: {
1736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Build kmp_int32 __kmpc_global_thread_num(ident_t *loc);
174ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    llvm::Type *TypeParams[] = {getIdentTyPointerTy()};
1756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    llvm::FunctionType *FnTy =
1766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, false);
1776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_global_thread_num");
1786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    break;
1796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return RTLFn;
1826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
183