Skip to content

Commit 2b13054

Browse files
committed
Cherry pick cheerp_typed_ptrcast
1 parent e539b57 commit 2b13054

File tree

9 files changed

+35
-4
lines changed

9 files changed

+35
-4
lines changed

clang/lib/CodeGen/CGExprScalar.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2246,7 +2246,8 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
22462246
// space, an address space conversion may end up as a bitcast.
22472247
return CGF.CGM.getTargetCodeGenInfo().performAddrSpaceCast(
22482248
CGF, Visit(E), E->getType()->getPointeeType().getAddressSpace(),
2249-
DestTy->getPointeeType().getAddressSpace(), ConvertType(DestTy));
2249+
DestTy->getPointeeType().getAddressSpace(), ConvertType(DestTy),
2250+
false, ConvertType(DestTy->getPointeeType()));
22502251
}
22512252
case CK_AtomicToNonAtomic:
22522253
case CK_NonAtomicToAtomic:

clang/lib/CodeGen/TargetInfo.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,11 +522,19 @@ LangAS TargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM,
522522

523523
llvm::Value *TargetCodeGenInfo::performAddrSpaceCast(
524524
CodeGen::CodeGenFunction &CGF, llvm::Value *Src, LangAS SrcAddr,
525-
LangAS DestAddr, llvm::Type *DestTy, bool isNonNull) const {
525+
LangAS DestAddr, llvm::Type *DestTy, bool isNonNull, llvm::Type* ElemTy) const {
526526
// Since target may map different address spaces in AST to the same address
527527
// space, an address space conversion may end up as a bitcast.
528528
if (auto *C = dyn_cast<llvm::Constant>(Src))
529529
return performAddrSpaceCast(CGF.CGM, C, SrcAddr, DestAddr, DestTy);
530+
if (CGF.getLangOpts().Cheerp && ElemTy &&
531+
(SrcAddr == LangAS::cheerp_bytelayout || SrcAddr == LangAS::cheerp_wasm) &&
532+
DestAddr == LangAS::cheerp_genericjs) {
533+
auto* F = CGF.CGM.getIntrinsic(llvm::Intrinsic::cheerp_typed_ptrcast, {DestTy, Src->getType()});
534+
llvm::CallBase* CB = CGF.Builder.CreateCall(F, {Src}, Src->hasName()? Src->getName() + ".ascast" : "");
535+
CB->addRetAttr(llvm::Attribute::get(CB->getContext(), llvm::Attribute::ElementType, ElemTy));
536+
return CB;
537+
}
530538
// Try to preserve the source's name to make IR more readable.
531539
return CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
532540
Src, DestTy, Src->hasName() ? Src->getName() + ".ascast" : "");

clang/lib/CodeGen/TargetInfo.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,8 @@ class TargetCodeGenInfo {
290290
virtual llvm::Value *performAddrSpaceCast(CodeGen::CodeGenFunction &CGF,
291291
llvm::Value *V, LangAS SrcAddr,
292292
LangAS DestAddr, llvm::Type *DestTy,
293-
bool IsNonNull = false) const;
293+
bool IsNonNull = false,
294+
llvm::Type* ElemTy = nullptr) const;
294295

295296
/// Perform address space cast of a constant expression of pointer type.
296297
/// \param V is the LLVM constant to be casted to another address space.

llvm/include/llvm/Cheerp/Utility.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ inline bool isBitCast(const llvm::Value* v)
262262
{
263263
case llvm::Intrinsic::cheerp_cast_user:
264264
case llvm::Intrinsic::cheerp_upcast_collapsed:
265+
case llvm::Intrinsic::cheerp_typed_ptrcast:
265266
return true;
266267
default:
267268
break;

llvm/include/llvm/IR/IntrinsicsCheerp.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ def int_cheerp_cast_user : Intrinsic<[llvm_anyptr_ty],
3737
[llvm_anyptr_ty],
3838
[]>;
3939

40+
def int_cheerp_typed_ptrcast : Intrinsic<[llvm_anyptr_ty],
41+
[llvm_anyptr_ty],
42+
[IntrNoMem]>;
43+
44+
4045
// Type safe memory allocation
4146
def int_cheerp_allocate : Intrinsic<[llvm_anyptr_ty],
4247
[llvm_ptr_ty,llvm_i32_ty]>;

llvm/lib/CheerpUtils/PointerAnalyzer.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,7 @@ PointerKindWrapper& PointerUsageVisitor::visitValue(PointerKindWrapper& ret, con
642642
case Intrinsic::cheerp_downcast:
643643
case Intrinsic::cheerp_upcast_collapsed:
644644
case Intrinsic::cheerp_cast_user:
645+
case Intrinsic::cheerp_typed_ptrcast:
645646
break;
646647
case Intrinsic::cheerp_allocate:
647648
case Intrinsic::cheerp_allocate_array:
@@ -891,6 +892,8 @@ PointerKindWrapper& PointerUsageVisitor::visitUse(PointerKindWrapper& ret, const
891892
return visitValue( ret, p, /*first*/ false );
892893
case Intrinsic::cheerp_virtualcast:
893894
return ret |= COMPLETE_OBJECT;
895+
case Intrinsic::cheerp_typed_ptrcast:
896+
return ret |= PointerKindWrapper(SPLIT_REGULAR, p);
894897
case Intrinsic::cheerp_downcast:
895898
{
896899
// Behaves like a cast if the offset is constant 0

llvm/lib/CheerpUtils/TypeOptimizer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,6 +1107,7 @@ Function* TypeOptimizer::rewriteIntrinsic(Function* F, FunctionType* FT)
11071107
}
11081108
case Intrinsic::cheerp_upcast_collapsed:
11091109
case Intrinsic::cheerp_cast_user:
1110+
case Intrinsic::cheerp_typed_ptrcast:
11101111
case Intrinsic::cheerp_downcast:
11111112
case Intrinsic::cheerp_virtualcast:
11121113
case Intrinsic::cheerp_make_complete_object:

llvm/lib/CheerpUtils/Utility.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ bool InlineableCache::isInlineableImpl(const Instruction& I)
331331
switch(II->getIntrinsicID())
332332
{
333333
case Intrinsic::cheerp_cast_user:
334+
case Intrinsic::cheerp_typed_ptrcast:
334335
case Intrinsic::cheerp_upcast_collapsed:
335336
case Intrinsic::cheerp_make_regular:
336337
return true;

llvm/lib/CheerpWriter/CheerpWriter.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,14 @@ CheerpWriter::COMPILE_INSTRUCTION_FEEDBACK CheerpWriter::handleBuiltinCall(const
873873
compileBitCast(&callV, PA.getPointerKindAssert(&callV), HIGHEST);
874874
return COMPILE_OK;
875875
}
876+
else if(intrinsicId==Intrinsic::cheerp_typed_ptrcast)
877+
{
878+
if(callV.use_empty())
879+
return COMPILE_EMPTY;
880+
881+
compileBitCast(&callV, PA.getPointerKindAssert(&callV), HIGHEST);
882+
return COMPILE_OK;
883+
}
876884
else if(intrinsicId==Intrinsic::cheerp_pointer_base)
877885
{
878886
compilePointerBase(*it, true);
@@ -2008,6 +2016,7 @@ void CheerpWriter::compilePointerBaseTyped(const Value* p, Type* elementType, bo
20082016
switch(II->getIntrinsicID())
20092017
{
20102018
case Intrinsic::cheerp_upcast_collapsed:
2019+
case Intrinsic::cheerp_typed_ptrcast:
20112020
case Intrinsic::cheerp_cast_user:
20122021
return compilePointerBaseTyped(II->getOperand(0), II->getParamElementType(0));
20132022
case Intrinsic::cheerp_make_regular:
@@ -2213,6 +2222,7 @@ void CheerpWriter::compilePointerOffset(const Value* p, PARENT_PRIORITY parentPr
22132222
switch(II->getIntrinsicID())
22142223
{
22152224
case Intrinsic::cheerp_upcast_collapsed:
2225+
case Intrinsic::cheerp_typed_ptrcast:
22162226
case Intrinsic::cheerp_cast_user:
22172227
compilePointerOffset(II->getOperand(0), parentPrio);
22182228
return;
@@ -4575,7 +4585,7 @@ void CheerpWriter::compileLoadElem(const LoadInst& li, Type* Ty, StructType* STy
45754585
assert(!STy);
45764586
//Optimize loads of single values from unions
45774587
compilePointerBase(ptrOp);
4578-
assert(ptrOp->getType()== Ty->getPointerTo());
4588+
assert(ptrOp->getType()== Ty->getPointerTo(ptrOp->getType()->getPointerAddressSpace()));
45794589
if(Ty->isIntegerTy(8))
45804590
stream << ".getUint8(";
45814591
else if(Ty->isIntegerTy(16))

0 commit comments

Comments
 (0)