clang 8.0.0

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.
40 return llvm::Function::Create(
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
70 CodeGenFunction::EmitNVPTXDevicePrintfCallExpr(const CallExpr *E,
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,
81 E->getDirectCallee()->getType()->getAs<FunctionProtoType>(),
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(), [&](const CallArg &A) {
87 return !A.getRValue(*this).isScalar();
88 })) {
89 CGM.ErrorUnsupported(E, "non-scalar arg to printf");
90 return RValue::get(llvm::ConstantInt::get(IntTy, 0));
91 }
92
93 // Construct and fill the args buffer that we'll pass to vprintf.
94 llvm::Value *BufferPtr;
95 if (Args.size() <= 1) {
96 // If there are no args, pass a null pointer to vprintf.
97 BufferPtr = llvm::ConstantPointerNull::get(llvm::Type::getInt8PtrTy(Ctx));
98 } else {
99 llvm::SmallVector<llvm::Type *, 8> ArgTypes;
100 for (unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I)
101 ArgTypes.push_back(Args[I].getRValue(*this).getScalarVal()->getType());
102
103 // Using llvm::StructType is correct only because printf doesn't accept
104 // aggregates. If we had to handle aggregates here, we'd have to manually
105 // compute the offsets within the alloca -- we wouldn't be able to assume
106 // that the alignment of the llvm type was the same as the alignment of the
107 // clang type.
108 llvm::Type *AllocaTy = llvm::StructType::create(ArgTypes, "printf_args");
109 llvm::Value *Alloca = CreateTempAlloca(AllocaTy);
110
111 for (unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I) {
112 llvm::Value *P = Builder.CreateStructGEP(AllocaTy, Alloca, I - 1);
113 llvm::Value *Arg = Args[I].getRValue(*this).getScalarVal();
114 Builder.CreateAlignedStore(Arg, P, DL.getPrefTypeAlignment(Arg->getType()));
115 }
116 BufferPtr = Builder.CreatePointerCast(Alloca, llvm::Type::getInt8PtrTy(Ctx));
117 }
118
119 // Invoke vprintf and return.
120 llvm::Function* VprintfFunc = GetVprintfDeclaration(CGM.getModule());
121 return RValue::get(Builder.CreateCall(
122 VprintfFunc, {Args[0].getRValue(*this).getScalarVal(), BufferPtr}));
123 }
clang::CodeGen::CodeGenModule::getDataLayout
const llvm::DataLayout & getDataLayout() const
Definition: CodeGenModule.h:661
clang::CodeGen::ReturnValueSlot
ReturnValueSlot - Contains the address where the return value of a function can be stored...
Definition: CGCall.h:361
clang::CodeGen::CodeGenTypeCache::IntTy
llvm::IntegerType * IntTy
int
Definition: CodeGenTypeCache.h:43
clang::ExternalLinkage
External linkage, which indicates that the entity can be referred to from other translation units...
Definition: Linkage.h:60
clang::CodeGen::CodeGenModule::getLLVMContext
llvm::LLVMContext & getLLVMContext()
Definition: CodeGenModule.h:670
clang::CallExpr::getNumArgs
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition: Expr.h:2540
P
StringRef P
Definition: ASTMatchersInternal.cpp:439
Value
Value
Definition: UninitializedValues.cpp:102
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6748
clang::CodeGen::CodeGenFunction::getTarget
const TargetInfo & getTarget() const
Definition: CodeGenFunction.h:1638
clang::CodeGen::CodeGenFunction::Builder
CGBuilderTy Builder
Definition: CodeGenFunction.h:263
clang::CodeGen::CodeGenFunction::CreateTempAlloca
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:106
clang::FunctionProtoType
Represents a prototype with parameter type info, e.g.
Definition: Type.h:3687
clang::CodeGen::RValue
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
Definition: CGValue.h:39
clang::CodeGen::CodeGenFunction::EmitCallArgs
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.
Definition: CodeGenFunction.h:4221
clang::CallExpr::getDirectCallee
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition: Expr.h:2532
GetVprintfDeclaration
static llvm::Function * GetVprintfDeclaration(llvm::Module &M)
Definition: CGGPUBuiltin.cpp:24
CodeGenFunction.h
clang::CallExpr::getBuiltinCallee
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
Definition: Expr.cpp:1368
clang::CodeGen::AlignmentSource::Type
The l-value was considered opaque, so the alignment was determined from a type.
clang::CodeGen::CodeGenFunction::EmitNVPTXDevicePrintfCallExpr
RValue EmitNVPTXDevicePrintfCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue)
Definition: CGGPUBuiltin.cpp:70
clang::CallExpr::arguments
arg_range arguments()
Definition: Expr.h:2585
llvm::SmallVector
Definition: LLVM.h:36
clang::CodeGen::CodeGenModule::ErrorUnsupported
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn&#39;t support the specified stmt yet.
Definition: CodeGenModule.cpp:702
clang
Dataflow Directional Tag Classes.
Definition: CFGReachabilityAnalysis.h:22
clang::CodeGen::CGBuilderTy::CreateStructGEP
Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, const llvm::Twine &Name="")
Definition: CGBuilder.h:172
clang::serialized_diags::create
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
Definition: SerializedDiagnosticPrinter.cpp:297
clang::CodeGen::CodeGenModule::getModule
llvm::Module & getModule() const
Definition: CodeGenModule.h:659
clang::CodeGen::CallArg
Definition: CGCall.h:215
clang::CallExpr
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2396
clang::CodeGen::RValue::get
static RValue get(llvm::Value *V)
Definition: CGValue.h:86
clang::CodeGen::CGBuilderTy::CreateAlignedStore
llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, CharUnits Align, bool IsVolatile=false)
Definition: CGBuilder.h:115
clang::ValueDecl::getType
QualType getType() const
Definition: Decl.h:648
clang::CodeGen::CodeGenFunction::CGM
CodeGenModule & CGM
Definition: CodeGenFunction.h:258
clang::CodeGen::CallArgList
CallArgList - Type for representing both the value and type of arguments in a call.
Definition: CGCall.h:260
Builtins.h
Defines enum values for all the target-independent builtin functions.
clang::Create
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.