Skip to content

Commit 1113d0a

Browse files
authored
[SYCL] Refactor address space handling in CodeGen library (#2864)
This patch reverts DPC++ customizations in CodeGen library enabling generic address space as default for SYCL mode. Based on feedback from the community there is a better way to get similar results. CodeGen TargetInfo object is be used to set default address space for global variables and stack allocations.
1 parent 22b9d01 commit 1113d0a

36 files changed

+813
-771
lines changed

clang/lib/Basic/Targets/SPIR.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,16 @@ class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo {
114114
return CC_SpirFunction;
115115
}
116116

117+
llvm::Optional<LangAS> getConstantAddressSpace() const override {
118+
// If we assign "opencl_constant" address space the following code becomes
119+
// illegal, because it can't be cast to any other address space:
120+
//
121+
// const char *getLiteral() {
122+
// return "AB";
123+
// }
124+
return LangAS::opencl_global;
125+
}
126+
117127
void setSupportedOpenCLOpts() override {
118128
// Assume all OpenCL extensions and optional core features are supported
119129
// for SPIR since it is a generic target.

clang/lib/CodeGen/CGCall.cpp

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4771,17 +4771,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
47714771
V->getType()->isIntegerTy())
47724772
V = Builder.CreateZExt(V, ArgInfo.getCoerceToType());
47734773

4774-
if (FirstIRArg < IRFuncTy->getNumParams()) {
4775-
const auto *LHSPtrTy =
4776-
dyn_cast_or_null<llvm::PointerType>(V->getType());
4777-
const auto *RHSPtrTy = dyn_cast_or_null<llvm::PointerType>(
4778-
IRFuncTy->getParamType(FirstIRArg));
4779-
if (LHSPtrTy && RHSPtrTy &&
4780-
LHSPtrTy->getAddressSpace() != RHSPtrTy->getAddressSpace())
4781-
V = Builder.CreateAddrSpaceCast(V,
4782-
IRFuncTy->getParamType(FirstIRArg));
4783-
}
4784-
47854774
// If the argument doesn't match, perform a bitcast to coerce it. This
47864775
// can happen due to trivial type mismatches.
47874776
if (FirstIRArg < IRFuncTy->getNumParams() &&
@@ -5002,20 +4991,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
50024991
if (!CallArgs.getCleanupsToDeactivate().empty())
50034992
deactivateArgCleanupsBeforeCall(*this, CallArgs);
50044993

5005-
// Addrspace cast to generic if necessary
5006-
for (unsigned i = 0; i < IRFuncTy->getNumParams(); ++i) {
5007-
if (auto *PtrTy = dyn_cast<llvm::PointerType>(IRCallArgs[i]->getType())) {
5008-
auto *ExpectedPtrType =
5009-
cast<llvm::PointerType>(IRFuncTy->getParamType(i));
5010-
unsigned ValueAS = PtrTy->getAddressSpace();
5011-
unsigned ExpectedAS = ExpectedPtrType->getAddressSpace();
5012-
if (ValueAS != ExpectedAS) {
5013-
IRCallArgs[i] = Builder.CreatePointerBitCastOrAddrSpaceCast(
5014-
IRCallArgs[i], ExpectedPtrType);
5015-
}
5016-
}
5017-
}
5018-
50194994
// Assert that the arguments we computed match up. The IR verifier
50204995
// will catch this, but this is a common enough source of problems
50214996
// during IRGen changes that it's way better for debugging to catch

clang/lib/CodeGen/CGClass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ Address CodeGenFunction::GetAddressOfBaseClass(
342342
EmitTypeCheck(TCK_Upcast, Loc, Value.getPointer(),
343343
DerivedTy, DerivedAlign, SkippedChecks);
344344
}
345-
return Builder.CreatePointerBitCastOrAddrSpaceCast(Value, BasePtrTy);
345+
return Builder.CreateBitCast(Value, BasePtrTy);
346346
}
347347

348348
llvm::BasicBlock *origBB = nullptr;

clang/lib/CodeGen/CGDecl.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,8 +1642,12 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
16421642
CGM.generateIntelFPGAAnnotation(&D, AnnotStr);
16431643
if (!AnnotStr.empty()) {
16441644
llvm::Value *V = address.getPointer();
1645-
EmitAnnotationCall(CGM.getIntrinsic(llvm::Intrinsic::var_annotation),
1646-
Builder.CreateBitCast(V, CGM.Int8PtrTy, V->getName()),
1645+
llvm::Type *DestPtrTy = llvm::PointerType::getInt8PtrTy(
1646+
CGM.getLLVMContext(), address.getAddressSpace());
1647+
llvm::Value *Arg = Builder.CreateBitCast(V, DestPtrTy, V->getName());
1648+
if (address.getAddressSpace() != 0)
1649+
Arg = Builder.CreateAddrSpaceCast(Arg, CGM.Int8PtrTy, V->getName());
1650+
EmitAnnotationCall(CGM.getIntrinsic(llvm::Intrinsic::var_annotation), Arg,
16471651
AnnotStr, D.getLocation());
16481652
}
16491653
}

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 10 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,8 +1125,10 @@ Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E,
11251125
CodeGenFunction::CFITCK_UnrelatedCast,
11261126
CE->getBeginLoc());
11271127
}
1128-
return Builder.CreatePointerBitCastOrAddrSpaceCast(
1129-
Addr, ConvertType(E->getType()));
1128+
return CE->getCastKind() != CK_AddressSpaceConversion
1129+
? Builder.CreateBitCast(Addr, ConvertType(E->getType()))
1130+
: Builder.CreateAddrSpaceCast(Addr,
1131+
ConvertType(E->getType()));
11301132
}
11311133
break;
11321134

@@ -1855,16 +1857,6 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
18551857
return;
18561858
}
18571859

1858-
if (auto *PtrTy = dyn_cast<llvm::PointerType>(Value->getType())) {
1859-
auto *ExpectedPtrType =
1860-
cast<llvm::PointerType>(Addr.getType()->getElementType());
1861-
unsigned ValueAS = PtrTy->getAddressSpace();
1862-
unsigned ExpectedAS = ExpectedPtrType->getAddressSpace();
1863-
if (ValueAS != ExpectedAS) {
1864-
Value =
1865-
Builder.CreatePointerBitCastOrAddrSpaceCast(Value, ExpectedPtrType);
1866-
}
1867-
}
18681860
llvm::StoreInst *Store = Builder.CreateStore(Value, Addr, Volatile);
18691861
if (isNontemporal) {
18701862
llvm::MDNode *Node =
@@ -4614,39 +4606,14 @@ EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {
46144606
EmitBlock(contBlock);
46154607

46164608
if (lhs && rhs) {
4617-
llvm::Value *lhsPtr = lhs->getPointer(*this);
4618-
llvm::Value *rhsPtr = rhs->getPointer(*this);
4619-
if (rhsPtr->getType() != lhsPtr->getType()) {
4620-
if (!getLangOpts().SYCLIsDevice)
4621-
llvm_unreachable(
4622-
"Unable to find a common address space for two pointers.");
4623-
4624-
auto CastToAS = [](llvm::Value *V, llvm::BasicBlock *BB, unsigned AS) {
4625-
auto *Ty = cast<llvm::PointerType>(V->getType());
4626-
if (Ty->getAddressSpace() == AS)
4627-
return V;
4628-
llvm::IRBuilder<> Builder(BB->getTerminator());
4629-
auto *TyAS = llvm::PointerType::get(Ty->getElementType(), AS);
4630-
return Builder.CreatePointerBitCastOrAddrSpaceCast(V, TyAS);
4631-
};
4632-
4633-
// Language rules define if it is legal to cast from one address space
4634-
// to another, and which address space we should use as a "common
4635-
// denominator". In SYCL, generic address space overlaps with all other
4636-
// address spaces.
4637-
unsigned GenericAS =
4638-
getContext().getTargetAddressSpace(LangAS::opencl_generic);
4639-
4640-
lhsPtr = CastToAS(lhsPtr, lhsBlock, GenericAS);
4641-
rhsPtr = CastToAS(rhsPtr, rhsBlock, GenericAS);
4642-
}
4643-
llvm::PHINode *phi = Builder.CreatePHI(lhsPtr->getType(), 2, "cond-lvalue");
4644-
phi->addIncoming(lhsPtr, lhsBlock);
4645-
phi->addIncoming(rhsPtr, rhsBlock);
4609+
llvm::PHINode *phi =
4610+
Builder.CreatePHI(lhs->getPointer(*this)->getType(), 2, "cond-lvalue");
4611+
phi->addIncoming(lhs->getPointer(*this), lhsBlock);
4612+
phi->addIncoming(rhs->getPointer(*this), rhsBlock);
46464613
Address result(phi, std::min(lhs->getAlignment(), rhs->getAlignment()));
46474614
AlignmentSource alignSource =
4648-
std::max(lhs->getBaseInfo().getAlignmentSource(),
4649-
rhs->getBaseInfo().getAlignmentSource());
4615+
std::max(lhs->getBaseInfo().getAlignmentSource(),
4616+
rhs->getBaseInfo().getAlignmentSource());
46504617
TBAAAccessInfo TBAAInfo = CGM.mergeTBAAInfoForConditionalOperator(
46514618
lhs->getTBAAInfo(), rhs->getTBAAInfo());
46524619
return MakeAddrLValue(result, expr->getType(), LValueBaseInfo(alignSource),

clang/lib/CodeGen/CGExprAgg.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -498,13 +498,7 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
498498
elementType.isTriviallyCopyableType(CGF.getContext())) {
499499
CodeGen::CodeGenModule &CGM = CGF.CGM;
500500
ConstantEmitter Emitter(CGF);
501-
LangAS AS = ArrayQTy.getAddressSpace();
502-
if (CGM.getLangOpts().SYCLIsDevice && AS == LangAS::Default) {
503-
// SYCL's default AS is 'generic', which can't be used to define constant
504-
// initializer data in. It is reasonable to keep it in the same AS
505-
// as string literals.
506-
AS = CGM.getStringLiteralAddressSpace();
507-
}
501+
LangAS AS = CGM.GetGlobalVarAddressSpace(/*VarDecl= */ nullptr);
508502
if (llvm::Constant *C = Emitter.tryEmitForInitializer(E, AS, ArrayQTy)) {
509503
auto GV = new llvm::GlobalVariable(
510504
CGM.getModule(), C->getType(),

clang/lib/CodeGen/CGExprScalar.cpp

Lines changed: 3 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,26 +1964,10 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
19641964
Value *Src = Visit(const_cast<Expr*>(E));
19651965
llvm::Type *SrcTy = Src->getType();
19661966
llvm::Type *DstTy = ConvertType(DestTy);
1967-
bool NeedAddrspaceCast = false;
19681967
if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
19691968
SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
1970-
// If we have the same address space in AST, which is then codegen'ed to
1971-
// different address spaces in IR, then an address space cast should be
1972-
// valid.
1973-
//
1974-
// This is the case for SYCL, where both types have Default address space
1975-
// in AST, but in IR one of them may be in opencl_private, and another in
1976-
// opencl_generic address space:
1977-
//
1978-
// int arr[5]; // automatic variable, default AS in AST,
1979-
// // private AS in IR
1980-
//
1981-
// char* p = arr; // default AS in AST, generic AS in IR
1982-
//
1983-
if (E->getType().getAddressSpace() != DestTy.getAddressSpace())
1984-
llvm_unreachable("wrong cast for pointers in different address spaces"
1985-
"(must be an address space cast)!");
1986-
NeedAddrspaceCast = true;
1969+
llvm_unreachable("wrong cast for pointers in different address spaces"
1970+
"(must be an address space cast)!");
19871971
}
19881972

19891973
if (CGF.SanOpts.has(SanitizerKind::CFIUnrelatedCast)) {
@@ -2022,14 +2006,6 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
20222006
}
20232007
}
20242008

2025-
if (NeedAddrspaceCast) {
2026-
llvm::Type *SrcPointeeTy = Src->getType()->getPointerElementType();
2027-
llvm::Type *SrcNewAS = llvm::PointerType::get(
2028-
SrcPointeeTy, cast<llvm::PointerType>(DstTy)->getAddressSpace());
2029-
2030-
Src = Builder.CreateAddrSpaceCast(Src, SrcNewAS);
2031-
}
2032-
20332009
// If Src is a fixed vector and Dst is a scalable vector, and both have the
20342010
// same element type, use the llvm.experimental.vector.insert intrinsic to
20352011
// perform the bitcast.
@@ -2966,53 +2942,6 @@ Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E) {
29662942
// Binary Operators
29672943
//===----------------------------------------------------------------------===//
29682944

2969-
static Value *insertAddressSpaceCast(Value *V, unsigned NewAS) {
2970-
auto *VTy = cast<llvm::PointerType>(V->getType());
2971-
if (VTy->getAddressSpace() == NewAS)
2972-
return V;
2973-
2974-
llvm::PointerType *VTyNewAS =
2975-
llvm::PointerType::get(VTy->getElementType(), NewAS);
2976-
2977-
if (auto *Constant = dyn_cast<llvm::Constant>(V))
2978-
return llvm::ConstantExpr::getAddrSpaceCast(Constant, VTyNewAS);
2979-
2980-
llvm::Instruction *NewV =
2981-
new llvm::AddrSpaceCastInst(V, VTyNewAS, V->getName() + ".ascast");
2982-
NewV->insertAfter(cast<llvm::Instruction>(V));
2983-
return NewV;
2984-
}
2985-
2986-
static void ensureSameAddrSpace(Value *&RHS, Value *&LHS,
2987-
bool CanInsertAddrspaceCast,
2988-
const LangOptions &Opts,
2989-
const ASTContext &Context) {
2990-
if (RHS->getType() == LHS->getType())
2991-
return;
2992-
2993-
auto *RHSTy = dyn_cast<llvm::PointerType>(RHS->getType());
2994-
auto *LHSTy = dyn_cast<llvm::PointerType>(LHS->getType());
2995-
if (!RHSTy || !LHSTy || RHSTy->getAddressSpace() == LHSTy->getAddressSpace())
2996-
return;
2997-
2998-
if (!CanInsertAddrspaceCast)
2999-
// Pointers have different address spaces and we cannot do anything with
3000-
// this.
3001-
llvm_unreachable("Pointers are expected to have the same address space.");
3002-
3003-
// Language rules define if it is legal to cast from one address space to
3004-
// another, and which address space we should use as a "common
3005-
// denominator". In SYCL, generic address space overlaps with all other
3006-
// address spaces.
3007-
if (Opts.SYCLIsDevice) {
3008-
unsigned GenericAS = Context.getTargetAddressSpace(LangAS::opencl_generic);
3009-
RHS = insertAddressSpaceCast(RHS, GenericAS);
3010-
LHS = insertAddressSpaceCast(LHS, GenericAS);
3011-
} else
3012-
llvm_unreachable("Unable to find a common address space for "
3013-
"two pointers.");
3014-
}
3015-
30162945
BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E) {
30172946
TestAndClearIgnoreResultAssign();
30182947
BinOpInfo Result;
@@ -4134,14 +4063,6 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,
41344063
RHS = Builder.CreateStripInvariantGroup(RHS);
41354064
}
41364065

4137-
// Expression operands may have the same addrspace in AST, but different
4138-
// addrspaces in LLVM IR, in which case an addrspacecast should be valid.
4139-
bool CanInsertAddrspaceCast =
4140-
LHSTy.getAddressSpace() == RHSTy.getAddressSpace();
4141-
4142-
ensureSameAddrSpace(RHS, LHS, CanInsertAddrspaceCast, CGF.getLangOpts(),
4143-
CGF.getContext());
4144-
41454066
Result = Builder.CreateICmp(UICmpOpc, LHS, RHS, "cmp");
41464067
}
41474068

@@ -4513,6 +4434,7 @@ static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E,
45134434
// exist in the source-level program.
45144435
}
45154436

4437+
45164438
Value *ScalarExprEmitter::
45174439
VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
45184440
TestAndClearIgnoreResultAssign();
@@ -4621,15 +4543,6 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
46214543
assert(!RHS && "LHS and RHS types must match");
46224544
return nullptr;
46234545
}
4624-
4625-
// Expressions may have the same addrspace in AST, but different address
4626-
// space in LLVM IR, in which case an addrspacecast should be valid.
4627-
bool CanInsertAddrspaceCast = rhsExpr->getType().getAddressSpace() ==
4628-
lhsExpr->getType().getAddressSpace();
4629-
4630-
ensureSameAddrSpace(RHS, LHS, CanInsertAddrspaceCast, CGF.getLangOpts(),
4631-
CGF.getContext());
4632-
46334546
return Builder.CreateSelect(CondV, LHS, RHS, "cond");
46344547
}
46354548

@@ -4664,14 +4577,6 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
46644577
if (!RHS)
46654578
return LHS;
46664579

4667-
// Expressions may have the same addrspace in AST, but different address
4668-
// space in LLVM IR, in which case an addrspacecast should be valid.
4669-
bool CanInsertAddrspaceCast = rhsExpr->getType().getAddressSpace() ==
4670-
lhsExpr->getType().getAddressSpace();
4671-
4672-
ensureSameAddrSpace(RHS, LHS, CanInsertAddrspaceCast, CGF.getLangOpts(),
4673-
CGF.getContext());
4674-
46754580
// Create a PHI node for the real part.
46764581
llvm::PHINode *PN = Builder.CreatePHI(LHS->getType(), 2, "cond");
46774582
PN->addIncoming(LHS, LHSBlock);

clang/lib/CodeGen/CGStmt.cpp

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,35 +1211,12 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
12111211
// If this function returns a reference, take the address of the expression
12121212
// rather than the value.
12131213
RValue Result = EmitReferenceBindingToExpr(RV);
1214-
llvm::Value *Val = Result.getScalarVal();
1215-
if (auto *PtrTy = dyn_cast<llvm::PointerType>(Val->getType())) {
1216-
auto *ExpectedPtrType =
1217-
cast<llvm::PointerType>(ReturnValue.getType()->getElementType());
1218-
unsigned ValueAS = PtrTy->getAddressSpace();
1219-
unsigned ExpectedAS = ExpectedPtrType->getAddressSpace();
1220-
if (ValueAS != ExpectedAS) {
1221-
Val = Builder.CreatePointerBitCastOrAddrSpaceCast(Val, ExpectedPtrType);
1222-
}
1223-
}
1224-
Builder.CreateStore(Val, ReturnValue);
1214+
Builder.CreateStore(Result.getScalarVal(), ReturnValue);
12251215
} else {
12261216
switch (getEvaluationKind(RV->getType())) {
12271217
case TEK_Scalar:
1228-
{
1229-
llvm::Value *Val = EmitScalarExpr(RV);
1230-
if (auto *PtrTy = dyn_cast<llvm::PointerType>(Val->getType())) {
1231-
auto *ExpectedPtrType =
1232-
cast<llvm::PointerType>(ReturnValue.getType()->getElementType());
1233-
unsigned ValueAS = PtrTy->getAddressSpace();
1234-
unsigned ExpectedAS = ExpectedPtrType->getAddressSpace();
1235-
if (ValueAS != ExpectedAS) {
1236-
Val =
1237-
Builder.CreatePointerBitCastOrAddrSpaceCast(Val, ExpectedPtrType);
1238-
}
1239-
}
1240-
Builder.CreateStore(Val, ReturnValue);
1218+
Builder.CreateStore(EmitScalarExpr(RV), ReturnValue);
12411219
break;
1242-
}
12431220
case TEK_Complex:
12441221
EmitComplexExprIntoLValue(RV, MakeAddrLValue(ReturnValue, RV->getType()),
12451222
/*isInit*/ true);

0 commit comments

Comments
 (0)