Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A few fixes to be more robust when handling non-default address spaces #267

Merged
merged 6 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions clang/lib/CodeGen/CGClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ CodeGenFunction::GetAddressOfDirectBaseInCompleteClass(Address This,
{
// Cheerp: if the base class has no members create a bitcast with cheerp specific intrinsic
if(Base->isEmpty() || Offset.isZero())
return GenerateUpcastCollapsed(This, ConvertType(Base), 0);
return GenerateUpcastCollapsed(This, ConvertType(Base), This.getAddressSpace());
else
{
// Get the layout.
Expand Down Expand Up @@ -565,7 +565,7 @@ CodeGenFunction::GenerateUpcast(Address Value,
//Cheerp: Check if the type is the expected one. If not create a builtin to handle this.
//This may happen when empty base classes are used
if(Value.getType()!=BasePtrTy)
Value = GenerateUpcastCollapsed(Value, BasePtrTy, 0);
Value = GenerateUpcastCollapsed(Value, BasePtrTy, Value.getAddressSpace());
return Value;
}

Expand All @@ -583,19 +583,19 @@ CodeGenFunction::GenerateDowncast(Address Value,
const CXXRecordDecl *Derived,
llvm::Value* BaseIdOffset)
{
QualType DerivedTy =
getContext().getCanonicalType(getContext().getTagDeclType(Derived));
llvm::Type *DerivedPtrTy = ConvertType(DerivedTy);
llvm::Type *DerivedTy =
ConvertType(getContext().getCanonicalType(getContext().getTagDeclType(Derived)));
llvm::Type *DerivedPtrTy = DerivedTy->getPointerTo(Value.getAddressSpace());

llvm::Type* types[] = { DerivedPtrTy->getPointerTo(), Value.getType() };
llvm::Type* types[] = { DerivedPtrTy, Value.getType() };

llvm::Function* intrinsic = llvm::Intrinsic::getDeclaration(&CGM.getModule(),
llvm::Intrinsic::cheerp_downcast, types);

llvm::CallBase* CB = Builder.CreateCall(intrinsic, {Value.getPointer(), BaseIdOffset});
CB->addParamAttr(0, llvm::Attribute::get(CB->getContext(), llvm::Attribute::ElementType, Value.getElementType()));
CB->addRetAttr(llvm::Attribute::get(CB->getContext(), llvm::Attribute::ElementType, DerivedPtrTy));
return Address(CB, DerivedPtrTy, Value.getAlignment());
CB->addRetAttr(llvm::Attribute::get(CB->getContext(), llvm::Attribute::ElementType, DerivedTy));
return Address(CB, DerivedTy, Value.getAlignment());
}

llvm::Value *
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/CodeGen/CGDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1553,11 +1553,12 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
allocaAlignment = alignment;
}

uint32_t AS = getTarget().isByteAddressable()? 0 : getContext().getTargetAddressSpace(Ty.getAddressSpace());
// Create the alloca. Note that we set the name separately from
// building the instruction so that it's there even in no-asserts
// builds.
address = CreateTempAlloca(allocaTy, allocaAlignment, D.getName(),
/*ArraySize=*/nullptr, &AllocaAddr);
/*ArraySize=*/nullptr, &AllocaAddr, AS);

// Don't emit lifetime markers for MSVC catch parameters. The lifetime of
// the catch parameter starts in the catchpad instruction, and we can't
Expand Down
17 changes: 10 additions & 7 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ llvm::Value *CodeGenFunction::EmitCastToVoidPtr(llvm::Value *value) {
Address CodeGenFunction::CreateTempAllocaWithoutCast(llvm::Type *Ty,
CharUnits Align,
const Twine &Name,
llvm::Value *ArraySize) {
auto Alloca = CreateTempAlloca(Ty, Name, ArraySize);
llvm::Value *ArraySize,
uint32_t AS) {
auto Alloca = CreateTempAlloca(Ty, Name, ArraySize, AS);
Alloca->setAlignment(Align.getAsAlign());
return Address(Alloca, Ty, Align);
}
Expand All @@ -79,8 +80,9 @@ Address CodeGenFunction::CreateTempAllocaWithoutCast(llvm::Type *Ty,
Address CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align,
const Twine &Name,
llvm::Value *ArraySize,
Address *AllocaAddr) {
auto Alloca = CreateTempAllocaWithoutCast(Ty, Align, Name, ArraySize);
Address *AllocaAddr,
uint32_t AS) {
auto Alloca = CreateTempAllocaWithoutCast(Ty, Align, Name, ArraySize, AS);
if (AllocaAddr)
*AllocaAddr = Alloca;
llvm::Value *V = Alloca.getPointer();
Expand Down Expand Up @@ -109,10 +111,11 @@ Address CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align,
/// insertion point of the builder.
llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(llvm::Type *Ty,
const Twine &Name,
llvm::Value *ArraySize) {
llvm::Value *ArraySize,
uint32_t AS) {
if (ArraySize)
return Builder.CreateAlloca(Ty, ArraySize, Name);
return new llvm::AllocaInst(Ty, CGM.getDataLayout().getAllocaAddrSpace(),
return new llvm::AllocaInst(Ty, AS == 0? CGM.getDataLayout().getAllocaAddrSpace() : AS,
ArraySize, Name, AllocaInsertPt);
}

Expand Down Expand Up @@ -4498,7 +4501,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
addr, CGM.getTypes().ConvertTypeForMem(FieldType), field->getName());
} else if (!CGM.getTarget().isByteAddressable() && CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field) == 0xffffffff) {
// Cheerp: If the first member is a struct we want to collapse it into the parent, and we use upcast_collapsed to access it
addr = GenerateUpcastCollapsed(addr, CGM.getTypes().ConvertTypeForMem(FieldType), 0);
addr = GenerateUpcastCollapsed(addr, CGM.getTypes().ConvertTypeForMem(FieldType), addr.getAddressSpace());
} else {
if (!IsInPreservedAIRegion &&
(!getDebugInfo() || !rec->hasAttr<BPFPreserveAccessIndexAttr>()))
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/CodeGen/CGExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1682,6 +1682,12 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
if (!getTarget().isByteAddressable() && !asmjs)
{
const CastExpr* castExpr = dyn_cast<CastExpr>(arg);
if (castExpr && castExpr->getCastKind() == CK_AddressSpaceConversion) {
// Peel the address space cast. The `new` expression returns a pointer to
// a non-default AS, but the placement new definition returns plain void*.
arg = castExpr->getSubExpr();
castExpr = dyn_cast<CastExpr>(arg);
}
if (castExpr == NULL ||
castExpr->getSubExpr()->getType()->getPointeeType().getCanonicalType().getUnqualifiedType()!=allocType.getCanonicalType().getUnqualifiedType())
{
Expand Down
9 changes: 6 additions & 3 deletions clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -2586,14 +2586,17 @@ class CodeGenFunction : public CodeGenTypeCache {
/// The cast is not performaed in CreateTempAllocaWithoutCast. This is
/// more efficient if the caller knows that the address will not be exposed.
llvm::AllocaInst *CreateTempAlloca(llvm::Type *Ty, const Twine &Name = "tmp",
llvm::Value *ArraySize = nullptr);
llvm::Value *ArraySize = nullptr,
uint32_t AS = 0);
Address CreateTempAlloca(llvm::Type *Ty, CharUnits align,
const Twine &Name = "tmp",
llvm::Value *ArraySize = nullptr,
Address *Alloca = nullptr);
Address *Alloca = nullptr,
uint32_t AS = 0);
Address CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits align,
const Twine &Name = "tmp",
llvm::Value *ArraySize = nullptr);
llvm::Value *ArraySize = nullptr,
uint32_t AS = 0);

/// CreateDefaultAlignedTempAlloca - This creates an alloca with the
/// default ABI alignment of the given LLVM type.
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/CheerpUtils/TypeOptimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,13 @@ std::pair<Constant*, uint8_t> TypeOptimizer::rewriteConstant(Constant* C, bool r
Constant* srcOperand = rewrittenOperand.first;
return std::make_pair(ConstantExpr::getBitCast(srcOperand, newTypeInfo.mappedType), 0);
}
case Instruction::AddrSpaceCast:
{
auto rewrittenOperand = rewriteConstant(CE->getOperand(0), false);
assert(rewrittenOperand.second == 0);
Constant* srcOperand = rewrittenOperand.first;
return std::make_pair(ConstantExpr::getPointerBitCastOrAddrSpaceCast(srcOperand, newTypeInfo.mappedType), 0);
}
case Instruction::IntToPtr:
{
return std::make_pair(ConstantExpr::getIntToPtr(CE->getOperand(0), newTypeInfo.mappedType), 0);
Expand Down Expand Up @@ -2085,6 +2092,7 @@ void TypeOptimizer::rewriteFunction(Function* F)
break;
}
case Instruction::BitCast:
case Instruction::AddrSpaceCast:
case Instruction::ExtractValue:
case Instruction::InsertValue:
case Instruction::IntToPtr:
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CheerpUtils/Utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ bool InlineableCache::isInlineableImpl(const Instruction& I)
case Instruction::PtrToInt:
case Instruction::IntToPtr:
case Instruction::ShuffleVector:
case Instruction::AddrSpaceCast:
return true;
case Instruction::ExtractElement:
case Instruction::InsertElement:
Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/CheerpWriter/CheerpWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2315,6 +2315,11 @@ void CheerpWriter::compileConstantExpr(const ConstantExpr* ce, PARENT_PRIORITY p
compileBitCast(ce, k, parentPrio);
break;
}
case Instruction::AddrSpaceCast:
{
compileOperand(ce->getOperand(0), parentPrio);
break;
}
case Instruction::IntToPtr:
{
compileOperand(ce->getOperand(0), parentPrio);
Expand Down Expand Up @@ -3740,6 +3745,11 @@ CheerpWriter::COMPILE_INSTRUCTION_FEEDBACK CheerpWriter::compileInlineableInstru
compileBitCast(&I, k, parentPrio);
return COMPILE_OK;
}
case Instruction::AddrSpaceCast:
{
compileOperand(I.getOperand(0), parentPrio);
return COMPILE_OK;
}
case Instruction::FPToSI:
case Instruction::FPToUI:
{
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CheerpWriter/PreExecute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,7 @@ Constant* PreExecute::findPointerFromGlobal(const DataLayout* DL,
Constant* GEP = ConstantExpr::getGetElementPtr(GV->getValueType(), GV, Indices);
assert(GEP->getType() == typeFound->getPointerTo(GEP->getType()->getPointerAddressSpace()));
if(GEP->getType() != memType)
return ConstantExpr::getBitCast(GEP, memType);
return ConstantExpr::getPointerBitCastOrAddrSpaceCast(GEP, memType);
return GEP;
}

Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/ExecutionEngine/ExecutionEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,9 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
}
return GV;
}
case Instruction::AddrSpaceCast: {
return getConstantValue(Op0);
}
case Instruction::Add:
case Instruction::FAdd:
case Instruction::Sub:
Expand Down
12 changes: 12 additions & 0 deletions llvm/lib/ExecutionEngine/Interpreter/Execution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1777,6 +1777,11 @@ GenericValue Interpreter::executeBitCastInst(Value *SrcVal, Type *DstTy,
return Dest;
}

GenericValue Interpreter::executeAddrSpaceCastInst(Value *SrcVal, Type *DstTy,
ExecutionContext &SF) {
return getOperandValue(SrcVal, SF);
}

void Interpreter::visitTruncInst(TruncInst &I) {
ExecutionContext &SF = ECStack.back();
SetValue(&I, executeTruncInst(I.getOperand(0), I.getType(), SF), SF);
Expand Down Expand Up @@ -1837,6 +1842,11 @@ void Interpreter::visitBitCastInst(BitCastInst &I) {
SetValue(&I, executeBitCastInst(I.getOperand(0), I.getType(), SF), SF);
}

void Interpreter::visitAddrSpaceCastInst(AddrSpaceCastInst &I) {
ExecutionContext &SF = ECStack.back();
SetValue(&I, executeAddrSpaceCastInst(I.getOperand(0), I.getType(), SF), SF);
}

void Interpreter::visitFreezeInst(FreezeInst &I) {
ExecutionContext &SF = ECStack.back();
SetValue(&I, executeFreezeInst(I.getOperand(0), SF), SF);
Expand Down Expand Up @@ -2223,6 +2233,8 @@ GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE,
return executeIntToPtrInst(CE->getOperand(0), CE->getType(), SF);
case Instruction::BitCast:
return executeBitCastInst(CE->getOperand(0), CE->getType(), SF);
case Instruction::AddrSpaceCast:
return executeAddrSpaceCastInst(CE->getOperand(0), CE->getType(), SF);
case Instruction::GetElementPtr:
return executeGEPOperation(CE->getOperand(0), gep_type_begin(CE),
gep_type_end(CE), SF);
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/ExecutionEngine/Interpreter/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {
void visitPtrToIntInst(PtrToIntInst &I);
void visitIntToPtrInst(IntToPtrInst &I);
void visitBitCastInst(BitCastInst &I);
void visitAddrSpaceCastInst(AddrSpaceCastInst &I);
void visitFreezeInst(FreezeInst &I);
void visitSelectInst(SelectInst &I);

Expand Down Expand Up @@ -304,6 +305,8 @@ class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {
ExecutionContext &SF);
GenericValue executeBitCastInst(Value *SrcVal, Type *DstTy,
ExecutionContext &SF);
GenericValue executeAddrSpaceCastInst(Value *SrcVal, Type *DstTy,
ExecutionContext &SF);
GenericValue executeFreezeInst(Value *SrcVal, ExecutionContext &SF);
GenericValue executeCastOperation(Instruction::CastOps opcode, Value *SrcVal,
Type *Ty, ExecutionContext &SF);
Expand Down
Loading