clang  6.0.0svn
CGGPUBuiltin.cpp
Go to the documentation of this file.
1 //===------ CGGPUBuiltin.cpp - Codegen for GPU builtins -------------------===//
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 // Generates code for built-in GPU calls which are not runtime-specific.
11 // (Runtime-specific codegen lives in programming model specific files.)
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "CodeGenFunction.h"
16 #include "clang/Basic/Builtins.h"
17 #include "llvm/IR/DataLayout.h"
18 #include "llvm/IR/Instruction.h"
19 #include "llvm/Support/MathExtras.h"
20 
21 using namespace clang;
22 using namespace CodeGen;
23 
24 static llvm::Function *GetVprintfDeclaration(llvm::Module &M) {
25  llvm::Type *ArgTypes[] = {llvm::Type::getInt8PtrTy(M.getContext()),
26  llvm::Type::getInt8PtrTy(M.getContext())};
27  llvm::FunctionType *VprintfFuncType = llvm::FunctionType::get(
28  llvm::Type::getInt32Ty(M.getContext()), ArgTypes, false);
29 
30  if (auto* F = M.getFunction("vprintf")) {
31  // Our CUDA system header declares vprintf with the right signature, so
32  // nobody else should have been able to declare vprintf with a bogus
33  // signature.
34  assert(F->getFunctionType() == VprintfFuncType);
35  return F;
36  }
37 
38  // vprintf doesn't already exist; create a declaration and insert it into the
39  // module.
41  VprintfFuncType, llvm::GlobalVariable::ExternalLinkage, "vprintf", &M);
42 }
43 
44 // Transforms a call to printf into a call to the NVPTX vprintf syscall (which
45 // isn't particularly special; it's invoked just like a regular function).
46 // vprintf takes two args: A format string, and a pointer to a buffer containing
47 // the varargs.
48 //
49 // For example, the call
50 //
51 // printf("format string", arg1, arg2, arg3);
52 //
53 // is converted into something resembling
54 //
55 // struct Tmp {
56 // Arg1 a1;
57 // Arg2 a2;
58 // Arg3 a3;
59 // };
60 // char* buf = alloca(sizeof(Tmp));
61 // *(Tmp*)buf = {a1, a2, a3};
62 // vprintf("format string", buf);
63 //
64 // buf is aligned to the max of {alignof(Arg1), ...}. Furthermore, each of the
65 // args is itself aligned to its preferred alignment.
66 //
67 // Note that by the time this function runs, E's args have already undergone the
68 // standard C vararg promotion (short -> int, float -> double, etc.).
69 RValue
71  ReturnValueSlot ReturnValue) {
72  assert(getTarget().getTriple().isNVPTX());
73  assert(E->getBuiltinCallee() == Builtin::BIprintf);
74  assert(E->getNumArgs() >= 1); // printf always has at least one arg.
75 
76  const llvm::DataLayout &DL = CGM.getDataLayout();
77  llvm::LLVMContext &Ctx = CGM.getLLVMContext();
78 
79  CallArgList Args;
80  EmitCallArgs(Args,
82  E->arguments(), E->getDirectCallee(),
83  /* ParamsToSkip = */ 0);
84 
85  // We don't know how to emit non-scalar varargs.
86  if (std::any_of(Args.begin() + 1, Args.end(),
87  [](const CallArg &A) { return !A.RV.isScalar(); })) {
88  CGM.ErrorUnsupported(E, "non-scalar arg to printf");
89  return RValue::get(llvm::ConstantInt::get(IntTy, 0));
90  }
91 
92  // Construct and fill the args buffer that we'll pass to vprintf.
93  llvm::Value *BufferPtr;
94  if (Args.size() <= 1) {
95  // If there are no args, pass a null pointer to vprintf.
96  BufferPtr = llvm::ConstantPointerNull::get(llvm::Type::getInt8PtrTy(Ctx));
97  } else {
99  for (unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I)
100  ArgTypes.push_back(Args[I].RV.getScalarVal()->getType());
101 
102  // Using llvm::StructType is correct only because printf doesn't accept
103  // aggregates. If we had to handle aggregates here, we'd have to manually
104  // compute the offsets within the alloca -- we wouldn't be able to assume
105  // that the alignment of the llvm type was the same as the alignment of the
106  // clang type.
107  llvm::Type *AllocaTy = llvm::StructType::create(ArgTypes, "printf_args");
108  llvm::Value *Alloca = CreateTempAlloca(AllocaTy);
109 
110  for (unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I) {
111  llvm::Value *P = Builder.CreateStructGEP(AllocaTy, Alloca, I - 1);
112  llvm::Value *Arg = Args[I].RV.getScalarVal();
113  Builder.CreateAlignedStore(Arg, P, DL.getPrefTypeAlignment(Arg->getType()));
114  }
115  BufferPtr = Builder.CreatePointerCast(Alloca, llvm::Type::getInt8PtrTy(Ctx));
116  }
117 
118  // Invoke vprintf and return.
119  llvm::Function* VprintfFunc = GetVprintfDeclaration(CGM.getModule());
120  return RValue::get(
121  Builder.CreateCall(VprintfFunc, {Args[0].RV.getScalarVal(), BufferPtr}));
122 }
const llvm::DataLayout & getDataLayout() const
ReturnValueSlot - Contains the address where the return value of a function can be stored...
Definition: CGCall.h:281
llvm::IntegerType * IntTy
int
External linkage, which indicates that the entity can be referred to from other translation units...
Definition: Linkage.h:61
llvm::LLVMContext & getLLVMContext()
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition: Expr.h:2266
StringRef P
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6099
const TargetInfo & getTarget() const
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
Definition: CGExpr.cpp:91
Represents a prototype with parameter type info, e.g.
Definition: Type.h:3170
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
Definition: CGValue.h:39
void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
EmitCallArgs - Emit call arguments for a function.
static llvm::Function * GetVprintfDeclaration(llvm::Module &M)
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
Definition: Expr.cpp:1279
The l-value was considered opaque, so the alignment was determined from a type.
RValue EmitNVPTXDevicePrintfCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue)
arg_range arguments()
Definition: Expr.h:2303
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn&#39;t support the specified stmt yet.
Dataflow Directional Tag Classes.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return 0.
Definition: Expr.cpp:1216
Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, const llvm::Twine &Name="")
Definition: CGBuilder.h:172
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
llvm::Module & getModule() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2209
static RValue get(llvm::Value *V)
Definition: CGValue.h:86
llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, CharUnits Align, bool IsVolatile=false)
Definition: CGBuilder.h:115
QualType getType() const
Definition: Decl.h:602
CallArgList - Type for representing both the value and type of arguments in a call.
Definition: CGCall.h:182
Defines enum values for all the target-independent builtin functions.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.