2010-01-10 12:58:08 +00:00
|
|
|
//===---- TargetInfo.cpp - Encapsulate target details -----------*- C++ -*-===//
|
2009-06-05 22:08:42 +00:00
|
|
|
//
|
2019-01-19 08:50:56 +00:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2009-06-05 22:08:42 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// These classes wrap the information about a call or function
|
|
|
|
// definition used to handle ABI compliancy.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-01-10 12:58:08 +00:00
|
|
|
#include "TargetInfo.h"
|
2009-06-05 22:08:42 +00:00
|
|
|
#include "ABIInfo.h"
|
2023-05-09 18:55:59 +03:00
|
|
|
#include "ABIInfoImpl.h"
|
2009-06-05 22:08:42 +00:00
|
|
|
#include "CodeGenFunction.h"
|
2018-12-11 03:18:39 +00:00
|
|
|
#include "clang/Basic/CodeGenOptions.h"
|
2013-10-30 21:53:58 +00:00
|
|
|
#include "clang/CodeGen/CGFunctionInfo.h"
|
2014-12-04 20:38:18 +00:00
|
|
|
#include "llvm/ADT/StringExtras.h"
|
2017-10-14 12:51:52 +00:00
|
|
|
#include "llvm/ADT/Twine.h"
|
2013-01-02 11:45:17 +00:00
|
|
|
#include "llvm/IR/Type.h"
|
2009-12-03 09:13:49 +00:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2014-05-02 09:33:20 +00:00
|
|
|
|
2009-06-05 22:08:42 +00:00
|
|
|
using namespace clang;
|
|
|
|
using namespace CodeGen;
|
|
|
|
|
2016-01-29 19:38:18 +00:00
|
|
|
LLVM_DUMP_METHOD void ABIArgInfo::dump() const {
|
2011-07-23 10:55:15 +00:00
|
|
|
raw_ostream &OS = llvm::errs();
|
2009-12-03 09:13:49 +00:00
|
|
|
OS << "(ABIArgInfo Kind=";
|
2009-06-05 22:08:42 +00:00
|
|
|
switch (TheKind) {
|
|
|
|
case Direct:
|
Kill off the 'coerce' ABI passing form. Now 'direct' and 'extend' always
have a "coerce to" type which often matches the default lowering of Clang
type to LLVM IR type, but the coerce case can be handled by making them
not be the same.
This simplifies things and fixes issues where X86-64 abi lowering would
return coerce after making preferred types exactly match up. This caused
us to compile:
typedef float v4f32 __attribute__((__vector_size__(16)));
v4f32 foo(v4f32 X) {
return X+X;
}
into this code at -O0:
define <4 x float> @foo(<4 x float> %X.coerce) nounwind {
entry:
%retval = alloca <4 x float>, align 16 ; <<4 x float>*> [#uses=2]
%coerce = alloca <4 x float>, align 16 ; <<4 x float>*> [#uses=2]
%X.addr = alloca <4 x float>, align 16 ; <<4 x float>*> [#uses=3]
store <4 x float> %X.coerce, <4 x float>* %coerce
%X = load <4 x float>* %coerce ; <<4 x float>> [#uses=1]
store <4 x float> %X, <4 x float>* %X.addr
%tmp = load <4 x float>* %X.addr ; <<4 x float>> [#uses=1]
%tmp1 = load <4 x float>* %X.addr ; <<4 x float>> [#uses=1]
%add = fadd <4 x float> %tmp, %tmp1 ; <<4 x float>> [#uses=1]
store <4 x float> %add, <4 x float>* %retval
%0 = load <4 x float>* %retval ; <<4 x float>> [#uses=1]
ret <4 x float> %0
}
Now we get:
define <4 x float> @foo(<4 x float> %X) nounwind {
entry:
%X.addr = alloca <4 x float>, align 16 ; <<4 x float>*> [#uses=3]
store <4 x float> %X, <4 x float>* %X.addr
%tmp = load <4 x float>* %X.addr ; <<4 x float>> [#uses=1]
%tmp1 = load <4 x float>* %X.addr ; <<4 x float>> [#uses=1]
%add = fadd <4 x float> %tmp, %tmp1 ; <<4 x float>> [#uses=1]
ret <4 x float> %add
}
This implements rdar://8248065
llvm-svn: 109733
2010-07-29 06:26:06 +00:00
|
|
|
OS << "Direct Type=";
|
2011-07-18 04:24:23 +00:00
|
|
|
if (llvm::Type *Ty = getCoerceToType())
|
Kill off the 'coerce' ABI passing form. Now 'direct' and 'extend' always
have a "coerce to" type which often matches the default lowering of Clang
type to LLVM IR type, but the coerce case can be handled by making them
not be the same.
This simplifies things and fixes issues where X86-64 abi lowering would
return coerce after making preferred types exactly match up. This caused
us to compile:
typedef float v4f32 __attribute__((__vector_size__(16)));
v4f32 foo(v4f32 X) {
return X+X;
}
into this code at -O0:
define <4 x float> @foo(<4 x float> %X.coerce) nounwind {
entry:
%retval = alloca <4 x float>, align 16 ; <<4 x float>*> [#uses=2]
%coerce = alloca <4 x float>, align 16 ; <<4 x float>*> [#uses=2]
%X.addr = alloca <4 x float>, align 16 ; <<4 x float>*> [#uses=3]
store <4 x float> %X.coerce, <4 x float>* %coerce
%X = load <4 x float>* %coerce ; <<4 x float>> [#uses=1]
store <4 x float> %X, <4 x float>* %X.addr
%tmp = load <4 x float>* %X.addr ; <<4 x float>> [#uses=1]
%tmp1 = load <4 x float>* %X.addr ; <<4 x float>> [#uses=1]
%add = fadd <4 x float> %tmp, %tmp1 ; <<4 x float>> [#uses=1]
store <4 x float> %add, <4 x float>* %retval
%0 = load <4 x float>* %retval ; <<4 x float>> [#uses=1]
ret <4 x float> %0
}
Now we get:
define <4 x float> @foo(<4 x float> %X) nounwind {
entry:
%X.addr = alloca <4 x float>, align 16 ; <<4 x float>*> [#uses=3]
store <4 x float> %X, <4 x float>* %X.addr
%tmp = load <4 x float>* %X.addr ; <<4 x float>> [#uses=1]
%tmp1 = load <4 x float>* %X.addr ; <<4 x float>> [#uses=1]
%add = fadd <4 x float> %tmp, %tmp1 ; <<4 x float>> [#uses=1]
ret <4 x float> %add
}
This implements rdar://8248065
llvm-svn: 109733
2010-07-29 06:26:06 +00:00
|
|
|
Ty->print(OS);
|
|
|
|
else
|
|
|
|
OS << "null";
|
2009-06-05 22:08:42 +00:00
|
|
|
break;
|
2009-06-06 09:36:29 +00:00
|
|
|
case Extend:
|
2009-12-03 09:13:49 +00:00
|
|
|
OS << "Extend";
|
2009-06-06 09:36:29 +00:00
|
|
|
break;
|
2009-06-05 22:08:42 +00:00
|
|
|
case Ignore:
|
2009-12-03 09:13:49 +00:00
|
|
|
OS << "Ignore";
|
2009-06-05 22:08:42 +00:00
|
|
|
break;
|
2014-02-01 00:04:45 +00:00
|
|
|
case InAlloca:
|
|
|
|
OS << "InAlloca Offset=" << getInAllocaFieldIndex();
|
|
|
|
break;
|
2009-06-05 22:08:42 +00:00
|
|
|
case Indirect:
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
OS << "Indirect Align=" << getIndirectAlign().getQuantity()
|
2011-07-15 18:23:44 +00:00
|
|
|
<< " ByVal=" << getIndirectByVal()
|
2010-09-16 20:42:02 +00:00
|
|
|
<< " Realign=" << getIndirectRealign();
|
2009-06-05 22:08:42 +00:00
|
|
|
break;
|
2020-05-05 20:24:53 -04:00
|
|
|
case IndirectAliased:
|
|
|
|
OS << "Indirect Align=" << getIndirectAlign().getQuantity()
|
|
|
|
<< " AadrSpace=" << getIndirectAddrSpace()
|
|
|
|
<< " Realign=" << getIndirectRealign();
|
|
|
|
break;
|
2009-06-05 22:08:42 +00:00
|
|
|
case Expand:
|
2009-12-03 09:13:49 +00:00
|
|
|
OS << "Expand";
|
2009-06-05 22:08:42 +00:00
|
|
|
break;
|
2016-03-11 04:30:43 +00:00
|
|
|
case CoerceAndExpand:
|
|
|
|
OS << "CoerceAndExpand Type=";
|
|
|
|
getCoerceAndExpandType()->print(OS);
|
|
|
|
break;
|
2009-06-05 22:08:42 +00:00
|
|
|
}
|
2009-12-03 09:13:49 +00:00
|
|
|
OS << ")\n";
|
2009-06-05 22:08:42 +00:00
|
|
|
}
|
|
|
|
|
2022-07-22 10:45:02 -07:00
|
|
|
TargetCodeGenInfo::TargetCodeGenInfo(std::unique_ptr<ABIInfo> Info)
|
|
|
|
: Info(std::move(Info)) {}
|
|
|
|
|
2020-04-30 02:50:57 +00:00
|
|
|
TargetCodeGenInfo::~TargetCodeGenInfo() = default;
|
2010-01-10 12:58:08 +00:00
|
|
|
|
2011-08-30 01:42:09 +00:00
|
|
|
// If someone can figure out a general rule for this, that would be great.
|
|
|
|
// It's probably just doomed to be platform-dependent, though.
|
|
|
|
unsigned TargetCodeGenInfo::getSizeOfUnwindException() const {
|
|
|
|
// Verified for:
|
|
|
|
// x86-64 FreeBSD, Linux, Darwin
|
|
|
|
// x86-32 FreeBSD, Linux, Darwin
|
2023-03-20 17:34:30 -04:00
|
|
|
// PowerPC Linux
|
2011-08-30 01:42:09 +00:00
|
|
|
// ARM Darwin (*not* EABI)
|
2013-01-31 12:13:10 +00:00
|
|
|
// AArch64 Linux
|
2011-08-30 01:42:09 +00:00
|
|
|
return 32;
|
|
|
|
}
|
|
|
|
|
2012-02-17 03:33:10 +00:00
|
|
|
bool TargetCodeGenInfo::isNoProtoCallVariadic(const CallArgList &args,
|
|
|
|
const FunctionNoProtoType *fnType) const {
|
2011-09-21 08:08:30 +00:00
|
|
|
// The following conventions are known to require this to be false:
|
|
|
|
// x86_stdcall
|
|
|
|
// MIPS
|
|
|
|
// For everything else, we just prefer false unless we opt out.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-05-08 13:44:39 +00:00
|
|
|
void
|
|
|
|
TargetCodeGenInfo::getDependentLibraryOption(llvm::StringRef Lib,
|
|
|
|
llvm::SmallString<24> &Opt) const {
|
|
|
|
// This assumes the user is passing a library name like "rt" instead of a
|
|
|
|
// filename like "librt.a/so", and that they don't care whether it's static or
|
|
|
|
// dynamic.
|
|
|
|
Opt = "-l";
|
|
|
|
Opt += Lib;
|
|
|
|
}
|
|
|
|
|
2016-06-30 09:06:33 +00:00
|
|
|
unsigned TargetCodeGenInfo::getOpenCLKernelCallingConv() const {
|
2017-06-01 07:18:49 +00:00
|
|
|
// OpenCL kernels are called via an explicit runtime API with arguments
|
|
|
|
// set with clSetKernelArg(), not as normal sub-functions.
|
|
|
|
// Return SPIR_KERNEL by default as the kernel calling convention to
|
|
|
|
// ensure the fingerprint is fixed such way that each OpenCL argument
|
|
|
|
// gets one matching argument in the produced kernel function argument
|
|
|
|
// list to enable feasible implementation of clSetKernelArg() with
|
|
|
|
// aggregates etc. In case we would use the default C calling conv here,
|
|
|
|
// clSetKernelArg() might break depending on the target-specific
|
|
|
|
// conventions; different targets might split structs passed as values
|
|
|
|
// to multiple function arguments etc.
|
|
|
|
return llvm::CallingConv::SPIR_KERNEL;
|
2016-06-30 09:06:33 +00:00
|
|
|
}
|
2016-07-20 19:21:11 +00:00
|
|
|
|
2016-12-15 08:09:08 +00:00
|
|
|
llvm::Constant *TargetCodeGenInfo::getNullPointer(const CodeGen::CodeGenModule &CGM,
|
|
|
|
llvm::PointerType *T, QualType QT) const {
|
|
|
|
return llvm::ConstantPointerNull::get(T);
|
|
|
|
}
|
|
|
|
|
Convert clang::LangAS to a strongly typed enum
Summary:
Convert clang::LangAS to a strongly typed enum
Currently both clang AST address spaces and target specific address spaces
are represented as unsigned which can lead to subtle errors if the wrong
type is passed. It is especially confusing in the CodeGen files as it is
not possible to see what kind of address space should be passed to a
function without looking at the implementation.
I originally made this change for our LLVM fork for the CHERI architecture
where we make extensive use of address spaces to differentiate between
capabilities and pointers. When merging the upstream changes I usually
run into some test failures or runtime crashes because the wrong kind of
address space is passed to a function. By converting the LangAS enum to a
C++11 we can catch these errors at compile time. Additionally, it is now
obvious from the function signature which kind of address space it expects.
I found the following errors while writing this patch:
- ItaniumRecordLayoutBuilder::LayoutField was passing a clang AST address
space to TargetInfo::getPointer{Width,Align}()
- TypePrinter::printAttributedAfter() prints the numeric value of the
clang AST address space instead of the target address space.
However, this code is not used so I kept the current behaviour
- initializeForBlockHeader() in CGBlocks.cpp was passing
LangAS::opencl_generic to TargetInfo::getPointer{Width,Align}()
- CodeGenFunction::EmitBlockLiteral() was passing a AST address space to
TargetInfo::getPointerWidth()
- CGOpenMPRuntimeNVPTX::translateParameter() passed a target address space
to Qualifiers::addAddressSpace()
- CGOpenMPRuntimeNVPTX::getParameterAddress() was using
llvm::Type::getPointerTo() with a AST address space
- clang_getAddressSpace() returns either a LangAS or a target address
space. As this is exposed to C I have kept the current behaviour and
added a comment stating that it is probably not correct.
Other than this the patch should not cause any functional changes.
Reviewers: yaxunl, pcc, bader
Reviewed By: yaxunl, bader
Subscribers: jlebar, jholewinski, nhaehnle, Anastasia, cfe-commits
Differential Revision: https://reviews.llvm.org/D38816
llvm-svn: 315871
2017-10-15 18:48:14 +00:00
|
|
|
LangAS TargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM,
|
|
|
|
const VarDecl *D) const {
|
2017-07-08 13:24:52 +00:00
|
|
|
assert(!CGM.getLangOpts().OpenCL &&
|
|
|
|
!(CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) &&
|
|
|
|
"Address space agnostic languages only");
|
Convert clang::LangAS to a strongly typed enum
Summary:
Convert clang::LangAS to a strongly typed enum
Currently both clang AST address spaces and target specific address spaces
are represented as unsigned which can lead to subtle errors if the wrong
type is passed. It is especially confusing in the CodeGen files as it is
not possible to see what kind of address space should be passed to a
function without looking at the implementation.
I originally made this change for our LLVM fork for the CHERI architecture
where we make extensive use of address spaces to differentiate between
capabilities and pointers. When merging the upstream changes I usually
run into some test failures or runtime crashes because the wrong kind of
address space is passed to a function. By converting the LangAS enum to a
C++11 we can catch these errors at compile time. Additionally, it is now
obvious from the function signature which kind of address space it expects.
I found the following errors while writing this patch:
- ItaniumRecordLayoutBuilder::LayoutField was passing a clang AST address
space to TargetInfo::getPointer{Width,Align}()
- TypePrinter::printAttributedAfter() prints the numeric value of the
clang AST address space instead of the target address space.
However, this code is not used so I kept the current behaviour
- initializeForBlockHeader() in CGBlocks.cpp was passing
LangAS::opencl_generic to TargetInfo::getPointer{Width,Align}()
- CodeGenFunction::EmitBlockLiteral() was passing a AST address space to
TargetInfo::getPointerWidth()
- CGOpenMPRuntimeNVPTX::translateParameter() passed a target address space
to Qualifiers::addAddressSpace()
- CGOpenMPRuntimeNVPTX::getParameterAddress() was using
llvm::Type::getPointerTo() with a AST address space
- clang_getAddressSpace() returns either a LangAS or a target address
space. As this is exposed to C I have kept the current behaviour and
added a comment stating that it is probably not correct.
Other than this the patch should not cause any functional changes.
Reviewers: yaxunl, pcc, bader
Reviewed By: yaxunl, bader
Subscribers: jlebar, jholewinski, nhaehnle, Anastasia, cfe-commits
Differential Revision: https://reviews.llvm.org/D38816
llvm-svn: 315871
2017-10-15 18:48:14 +00:00
|
|
|
return D ? D->getType().getAddressSpace() : LangAS::Default;
|
2017-07-08 13:24:52 +00:00
|
|
|
}
|
|
|
|
|
2016-12-15 08:09:08 +00:00
|
|
|
llvm::Value *TargetCodeGenInfo::performAddrSpaceCast(
|
Convert clang::LangAS to a strongly typed enum
Summary:
Convert clang::LangAS to a strongly typed enum
Currently both clang AST address spaces and target specific address spaces
are represented as unsigned which can lead to subtle errors if the wrong
type is passed. It is especially confusing in the CodeGen files as it is
not possible to see what kind of address space should be passed to a
function without looking at the implementation.
I originally made this change for our LLVM fork for the CHERI architecture
where we make extensive use of address spaces to differentiate between
capabilities and pointers. When merging the upstream changes I usually
run into some test failures or runtime crashes because the wrong kind of
address space is passed to a function. By converting the LangAS enum to a
C++11 we can catch these errors at compile time. Additionally, it is now
obvious from the function signature which kind of address space it expects.
I found the following errors while writing this patch:
- ItaniumRecordLayoutBuilder::LayoutField was passing a clang AST address
space to TargetInfo::getPointer{Width,Align}()
- TypePrinter::printAttributedAfter() prints the numeric value of the
clang AST address space instead of the target address space.
However, this code is not used so I kept the current behaviour
- initializeForBlockHeader() in CGBlocks.cpp was passing
LangAS::opencl_generic to TargetInfo::getPointer{Width,Align}()
- CodeGenFunction::EmitBlockLiteral() was passing a AST address space to
TargetInfo::getPointerWidth()
- CGOpenMPRuntimeNVPTX::translateParameter() passed a target address space
to Qualifiers::addAddressSpace()
- CGOpenMPRuntimeNVPTX::getParameterAddress() was using
llvm::Type::getPointerTo() with a AST address space
- clang_getAddressSpace() returns either a LangAS or a target address
space. As this is exposed to C I have kept the current behaviour and
added a comment stating that it is probably not correct.
Other than this the patch should not cause any functional changes.
Reviewers: yaxunl, pcc, bader
Reviewed By: yaxunl, bader
Subscribers: jlebar, jholewinski, nhaehnle, Anastasia, cfe-commits
Differential Revision: https://reviews.llvm.org/D38816
llvm-svn: 315871
2017-10-15 18:48:14 +00:00
|
|
|
CodeGen::CodeGenFunction &CGF, llvm::Value *Src, LangAS SrcAddr,
|
|
|
|
LangAS DestAddr, llvm::Type *DestTy, bool isNonNull) const {
|
2016-12-15 08:09:08 +00:00
|
|
|
// Since target may map different address spaces in AST to the same address
|
|
|
|
// space, an address space conversion may end up as a bitcast.
|
2017-07-08 13:24:52 +00:00
|
|
|
if (auto *C = dyn_cast<llvm::Constant>(Src))
|
|
|
|
return performAddrSpaceCast(CGF.CGM, C, SrcAddr, DestAddr, DestTy);
|
2019-07-10 17:10:05 +00:00
|
|
|
// Try to preserve the source's name to make IR more readable.
|
2023-11-11 10:57:44 -05:00
|
|
|
return CGF.Builder.CreateAddrSpaceCast(
|
2019-07-10 17:10:05 +00:00
|
|
|
Src, DestTy, Src->hasName() ? Src->getName() + ".ascast" : "");
|
2016-12-15 08:09:08 +00:00
|
|
|
}
|
|
|
|
|
2017-07-08 13:24:52 +00:00
|
|
|
llvm::Constant *
|
|
|
|
TargetCodeGenInfo::performAddrSpaceCast(CodeGenModule &CGM, llvm::Constant *Src,
|
Convert clang::LangAS to a strongly typed enum
Summary:
Convert clang::LangAS to a strongly typed enum
Currently both clang AST address spaces and target specific address spaces
are represented as unsigned which can lead to subtle errors if the wrong
type is passed. It is especially confusing in the CodeGen files as it is
not possible to see what kind of address space should be passed to a
function without looking at the implementation.
I originally made this change for our LLVM fork for the CHERI architecture
where we make extensive use of address spaces to differentiate between
capabilities and pointers. When merging the upstream changes I usually
run into some test failures or runtime crashes because the wrong kind of
address space is passed to a function. By converting the LangAS enum to a
C++11 we can catch these errors at compile time. Additionally, it is now
obvious from the function signature which kind of address space it expects.
I found the following errors while writing this patch:
- ItaniumRecordLayoutBuilder::LayoutField was passing a clang AST address
space to TargetInfo::getPointer{Width,Align}()
- TypePrinter::printAttributedAfter() prints the numeric value of the
clang AST address space instead of the target address space.
However, this code is not used so I kept the current behaviour
- initializeForBlockHeader() in CGBlocks.cpp was passing
LangAS::opencl_generic to TargetInfo::getPointer{Width,Align}()
- CodeGenFunction::EmitBlockLiteral() was passing a AST address space to
TargetInfo::getPointerWidth()
- CGOpenMPRuntimeNVPTX::translateParameter() passed a target address space
to Qualifiers::addAddressSpace()
- CGOpenMPRuntimeNVPTX::getParameterAddress() was using
llvm::Type::getPointerTo() with a AST address space
- clang_getAddressSpace() returns either a LangAS or a target address
space. As this is exposed to C I have kept the current behaviour and
added a comment stating that it is probably not correct.
Other than this the patch should not cause any functional changes.
Reviewers: yaxunl, pcc, bader
Reviewed By: yaxunl, bader
Subscribers: jlebar, jholewinski, nhaehnle, Anastasia, cfe-commits
Differential Revision: https://reviews.llvm.org/D38816
llvm-svn: 315871
2017-10-15 18:48:14 +00:00
|
|
|
LangAS SrcAddr, LangAS DestAddr,
|
2017-07-08 13:24:52 +00:00
|
|
|
llvm::Type *DestTy) const {
|
|
|
|
// Since target may map different address spaces in AST to the same address
|
|
|
|
// space, an address space conversion may end up as a bitcast.
|
|
|
|
return llvm::ConstantExpr::getPointerCast(Src, DestTy);
|
|
|
|
}
|
|
|
|
|
2017-08-04 18:16:31 +00:00
|
|
|
llvm::SyncScope::ID
|
2019-03-25 20:54:00 +00:00
|
|
|
TargetCodeGenInfo::getLLVMSyncScopeID(const LangOptions &LangOpts,
|
|
|
|
SyncScope Scope,
|
|
|
|
llvm::AtomicOrdering Ordering,
|
|
|
|
llvm::LLVMContext &Ctx) const {
|
|
|
|
return Ctx.getOrInsertSyncScopeID(""); /* default sync scope */
|
2017-08-04 18:16:31 +00:00
|
|
|
}
|
|
|
|
|
2023-05-09 18:55:59 +03:00
|
|
|
void TargetCodeGenInfo::addStackProbeTargetAttributes(
|
|
|
|
const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const {
|
|
|
|
if (llvm::Function *Fn = dyn_cast_or_null<llvm::Function>(GV)) {
|
|
|
|
if (CGM.getCodeGenOpts().StackProbeSize != 4096)
|
|
|
|
Fn->addFnAttr("stack-probe-size",
|
|
|
|
llvm::utostr(CGM.getCodeGenOpts().StackProbeSize));
|
|
|
|
if (CGM.getCodeGenOpts().NoStackArgProbe)
|
|
|
|
Fn->addFnAttr("no-stack-arg-probe");
|
|
|
|
}
|
2009-06-05 22:08:42 +00:00
|
|
|
}
|
|
|
|
|
2023-05-09 18:55:59 +03:00
|
|
|
/// Create an OpenCL kernel for an enqueued block.
|
2009-06-05 22:08:42 +00:00
|
|
|
///
|
2023-05-09 18:55:59 +03:00
|
|
|
/// The kernel has the same function type as the block invoke function. Its
|
|
|
|
/// name is the name of the block invoke function postfixed with "_kernel".
|
|
|
|
/// It simply calls the block invoke function then returns.
|
|
|
|
llvm::Value *TargetCodeGenInfo::createEnqueuedBlockKernel(
|
|
|
|
CodeGenFunction &CGF, llvm::Function *Invoke, llvm::Type *BlockTy) const {
|
|
|
|
auto *InvokeFT = Invoke->getFunctionType();
|
|
|
|
auto &C = CGF.getLLVMContext();
|
|
|
|
std::string Name = Invoke->getName().str() + "_kernel";
|
|
|
|
auto *FT = llvm::FunctionType::get(llvm::Type::getVoidTy(C),
|
|
|
|
InvokeFT->params(), false);
|
|
|
|
auto *F = llvm::Function::Create(FT, llvm::GlobalValue::ExternalLinkage, Name,
|
|
|
|
&CGF.CGM.getModule());
|
|
|
|
llvm::CallingConv::ID KernelCC =
|
|
|
|
CGF.getTypes().ClangCallConvToLLVMCallConv(CallingConv::CC_OpenCLKernel);
|
|
|
|
F->setCallingConv(KernelCC);
|
2009-06-05 22:08:42 +00:00
|
|
|
|
2023-05-09 18:55:59 +03:00
|
|
|
llvm::AttrBuilder KernelAttrs(C);
|
2009-06-05 22:08:42 +00:00
|
|
|
|
2023-05-09 18:55:59 +03:00
|
|
|
// FIXME: This is missing setTargetAttributes
|
|
|
|
CGF.CGM.addDefaultFunctionDefinitionAttributes(KernelAttrs);
|
|
|
|
F->addFnAttrs(KernelAttrs);
|
2009-06-05 22:08:42 +00:00
|
|
|
|
2023-05-09 18:55:59 +03:00
|
|
|
auto IP = CGF.Builder.saveIP();
|
|
|
|
auto *BB = llvm::BasicBlock::Create(C, "entry", F);
|
|
|
|
auto &Builder = CGF.Builder;
|
|
|
|
Builder.SetInsertPoint(BB);
|
|
|
|
llvm::SmallVector<llvm::Value *, 2> Args(llvm::make_pointer_range(F->args()));
|
|
|
|
llvm::CallInst *Call = Builder.CreateCall(Invoke, Args);
|
|
|
|
Call->setCallingConv(Invoke->getCallingConv());
|
2011-11-18 01:25:50 +00:00
|
|
|
|
2023-05-09 18:55:59 +03:00
|
|
|
Builder.CreateRetVoid();
|
|
|
|
Builder.restoreIP(IP);
|
|
|
|
return F;
|
2009-06-05 22:08:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace {
|
2010-01-10 12:58:08 +00:00
|
|
|
class DefaultTargetCodeGenInfo : public TargetCodeGenInfo {
|
|
|
|
public:
|
2010-07-29 02:01:43 +00:00
|
|
|
DefaultTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)
|
2020-04-30 02:50:57 +00:00
|
|
|
: TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {}
|
2010-01-10 12:58:08 +00:00
|
|
|
};
|
2023-05-09 18:55:59 +03:00
|
|
|
} // namespace
|
2023-05-09 18:41:05 +03:00
|
|
|
|
|
|
|
std::unique_ptr<TargetCodeGenInfo>
|
|
|
|
CodeGen::createDefaultTargetCodeGenInfo(CodeGenModule &CGM) {
|
|
|
|
return std::make_unique<DefaultTargetCodeGenInfo>(CGM.getTypes());
|
|
|
|
}
|