Skip to content

Commit d50e735

Browse files
committed
Remove the need for getPointerElementType in compilePointerBase
The call to getPointerElementType still exists, but it should disappear naturally when more AS changes are merged into master.
1 parent 2b13054 commit d50e735

File tree

7 files changed

+66
-11
lines changed

7 files changed

+66
-11
lines changed

clang/lib/CodeGen/CGExprScalar.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2377,6 +2377,16 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
23772377
Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
23782378

23792379
auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2380+
bool asmjs = CGF.CurFn && CGF.CurFn->getSection() == StringRef("asmjs");
2381+
2382+
if (CGF.getLangOpts().Cheerp && !asmjs) {
2383+
QualType PointeeType = DestTy->getAs<PointerType>()->getPointeeType();
2384+
llvm::Type* ElemTy = CGF.ConvertTypeForMem(PointeeType);
2385+
auto* F = CGF.CGM.getIntrinsic(llvm::Intrinsic::cheerp_typed_ptrcast, {DestLLVMTy, DestLLVMTy});
2386+
llvm::CallBase* CB = Builder.CreateCall(F, {IntToPtr}, IntToPtr->hasName() ? IntToPtr->getName() + ".i2p" : "");
2387+
CB->addRetAttr(llvm::Attribute::get(CB->getContext(), llvm::Attribute::ElementType, ElemTy));
2388+
IntToPtr = CB;
2389+
}
23802390

23812391
if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) {
23822392
// Going from integer to pointer that could be dynamic requires reloading

llvm/include/llvm/Cheerp/Utility.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ const static int V8MaxLiteralProperties = 8;
102102
bool isNopCast(const llvm::Value* val);
103103
bool isValidVoidPtrSource(const llvm::Value* val, std::set<const llvm::PHINode*>& visitedPhis);
104104

105+
const llvm::IntToPtrInst* getAsIntToPtrInst(const llvm::Value* val);
106+
105107
inline void assertPointerElementOrOpaque(llvm::Type* pointer, llvm::Type* pointee)
106108
{
107109
assert(llvm::isa<llvm::PointerType>(pointer));

llvm/include/llvm/Cheerp/Writer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ class CheerpWriter final : public CheerpBaseWriter
372372
/**
373373
* Compile the pointer base.
374374
*/
375-
void compilePointerBase(const llvm::Value*, bool forEscapingPointer=false);
375+
void compilePointerBase(const llvm::Value*, bool forEscapingPointer=false, bool useGPET=false);
376376
void compilePointerBaseTyped(const llvm::Value*, llvm::Type* elementType, bool forEscapingPointer=false);
377377

378378
/**

llvm/lib/CheerpUtils/PointerAnalyzer.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,8 @@ PointerKindWrapper& PointerUsageVisitor::visitValue(PointerKindWrapper& ret, con
643643
case Intrinsic::cheerp_upcast_collapsed:
644644
case Intrinsic::cheerp_cast_user:
645645
case Intrinsic::cheerp_typed_ptrcast:
646+
if (isa<IntToPtrInst>(intrinsic->getArgOperand(0)))
647+
return CacheAndReturn(visitValue(ret, intrinsic->getArgOperand(0), false));
646648
break;
647649
case Intrinsic::cheerp_allocate:
648650
case Intrinsic::cheerp_allocate_array:
@@ -855,7 +857,7 @@ PointerKindWrapper& PointerUsageVisitor::visitUse(PointerKindWrapper& ret, const
855857
if ( !I->isEquality() )
856858
return ret |= PointerKindWrapper(SPLIT_REGULAR, p);
857859
Value* Other = I->getOperand(0) == U->get() ? I->getOperand(1) : I->getOperand(0);
858-
if ( visitRawChain(Other) || isa<IntToPtrInst>(Other))
860+
if ( visitRawChain(Other) || getAsIntToPtrInst(Other))
859861
return ret |= PointerKindWrapper(SPLIT_REGULAR, p);
860862
else
861863
return ret |= COMPLETE_OBJECT;

llvm/lib/CheerpUtils/Utility.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,16 @@ bool isValidVoidPtrSource(const Value* val, std::set<const PHINode*>& visitedPhi
8484
return false;
8585
}
8686

87+
const llvm::IntToPtrInst* getAsIntToPtrInst(const llvm::Value* val)
88+
{
89+
if (const llvm::IntrinsicInst* intrinsic = llvm::dyn_cast<llvm::IntrinsicInst>(val))
90+
if (intrinsic->getIntrinsicID() == llvm::Intrinsic::cheerp_typed_ptrcast)
91+
val = intrinsic->getArgOperand(0);
92+
if (const llvm::IntToPtrInst* inttoptr = llvm::dyn_cast<llvm::IntToPtrInst>(val))
93+
return inttoptr;
94+
return nullptr;
95+
}
96+
8797
int32_t partialOffset(llvm::Type* & curType, llvm::Type* alternative, const llvm::DataLayout& DL, const int32_t index)
8898
{
8999
int32_t partialOffset = 0;

llvm/lib/CheerpWriter/CheerpWriter.cpp

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1622,9 +1622,9 @@ void CheerpWriter::compileEqualPointersComparison(const llvm::Value* lhs, const
16221622
isInlineable(*cast<Instruction>(lhs), PA));
16231623
assert(rhsKind != COMPLETE_OBJECT || !isa<Instruction>(rhs) ||
16241624
isInlineable(*cast<Instruction>(rhs), PA));
1625-
compilePointerBase(lhs);
1625+
compilePointerBase(lhs, false, true);
16261626
stream << compareString;
1627-
compilePointerBase(rhs);
1627+
compilePointerBase(rhs, false, true);
16281628
stream << joinString;
16291629
compilePointerOffset(lhs, COMPARISON);
16301630
stream << compareString;
@@ -1634,9 +1634,9 @@ void CheerpWriter::compileEqualPointersComparison(const llvm::Value* lhs, const
16341634
{
16351635
assert(lhsKind != COMPLETE_OBJECT);
16361636
assert(rhsKind != COMPLETE_OBJECT);
1637-
compilePointerBase(lhs);
1637+
compilePointerBase(lhs, false, true);
16381638
stream << compareString;
1639-
compilePointerBase(rhs);
1639+
compilePointerBase(rhs, false, true);
16401640
stream << joinString;
16411641
compilePointerOffset(lhs, COMPARISON);
16421642
stream << compareString;
@@ -1732,6 +1732,7 @@ void CheerpWriter::compileCompleteObject(const Value* p, const Value* offset)
17321732
return;
17331733
}
17341734

1735+
17351736
const llvm::Instruction* I = dyn_cast<Instruction>(p);
17361737
if (I && !isInlineable(*I, PA) &&
17371738
(isGEP(I) || isBitCast(I)) && PA.getPointerKindAssert(I) == COMPLETE_OBJECT)
@@ -1960,9 +1961,32 @@ void CheerpWriter::compileHeapAccess(const Value* p, Type* t, uint32_t offset)
19601961
stream << pointerShiftOperator() << shift;
19611962
stream << ']';
19621963
}
1963-
void CheerpWriter::compilePointerBase(const Value* p, bool forEscapingPointer)
1964+
void CheerpWriter::compilePointerBase(const Value* p, bool forEscapingPointer, bool useGPET)
19641965
{
1965-
compilePointerBaseTyped(p, p->getType()->getPointerElementType(), forEscapingPointer);
1966+
if(const IntrinsicInst* II=dyn_cast<IntrinsicInst>(p))
1967+
{
1968+
switch(II->getIntrinsicID())
1969+
{
1970+
case Intrinsic::cheerp_upcast_collapsed:
1971+
case Intrinsic::cheerp_typed_ptrcast:
1972+
case Intrinsic::cheerp_cast_user:
1973+
return compilePointerBaseTyped(II->getOperand(0), II->getParamElementType(0), forEscapingPointer);
1974+
default:
1975+
break;
1976+
}
1977+
}
1978+
1979+
POINTER_KIND kind = PA.getPointerKind(p);
1980+
1981+
if (kind != RAW && (kind != CONSTANT || isa<ConstantPointerNull>(p)))
1982+
{
1983+
// point element type is not used in this case, so it can be null
1984+
compilePointerBaseTyped(p, nullptr, forEscapingPointer);
1985+
}
1986+
else if (useGPET || isa<BitCastInst>(p) || isa<UndefValue>(p))
1987+
compilePointerBaseTyped(p, p->getType()->getPointerElementType(), forEscapingPointer);
1988+
else
1989+
llvm::report_fatal_error("Missing typed ptrcast intrinsic and no GPET allowed");
19661990
}
19671991

19681992
void CheerpWriter::compilePointerBaseTyped(const Value* p, Type* elementType, bool forEscapingPointer)
@@ -2018,6 +2042,7 @@ void CheerpWriter::compilePointerBaseTyped(const Value* p, Type* elementType, bo
20182042
case Intrinsic::cheerp_upcast_collapsed:
20192043
case Intrinsic::cheerp_typed_ptrcast:
20202044
case Intrinsic::cheerp_cast_user:
2045+
assert(elementType == II->getParamElementType(0));
20212046
return compilePointerBaseTyped(II->getOperand(0), II->getParamElementType(0));
20222047
case Intrinsic::cheerp_make_regular:
20232048
return compileCompleteObject(II->getOperand(0));
@@ -2171,7 +2196,7 @@ void CheerpWriter::compilePointerOffset(const Value* p, PARENT_PRIORITY parentPr
21712196
// null must be handled first, even if it is bytelayout
21722197
else if(kind == CONSTANT || isa<UndefValue>(p))
21732198
{
2174-
if (const IntToPtrInst* ITP = dyn_cast<IntToPtrInst>(p))
2199+
if (const IntToPtrInst* ITP = getAsIntToPtrInst(p))
21752200
{
21762201
ConstantInt* CI = cast<ConstantInt>(ITP->getOperand(0));
21772202
stream << CI->getSExtValue();
@@ -3034,10 +3059,10 @@ void CheerpWriter::compileMethodArgs(User::const_op_iterator it, User::const_op_
30343059
(argKind == COMPLETE_OBJECT && curKind == BYTE_LAYOUT))
30353060
{
30363061
if(F && PA.getConstantOffsetForPointer(&*arg_it))
3037-
compilePointerBase(*cur, true);
3062+
compilePointerBase(*cur, true, true);
30383063
else
30393064
{
3040-
compilePointerBase(*cur, true);
3065+
compilePointerBase(*cur, true, true);
30413066
stream << ',';
30423067
compilePointerOffset(*cur, LOWEST, true);
30433068
}

llvm/lib/CheerpWriter/PreExecute.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,10 @@ static GenericValue pre_execute_upcast(FunctionType *FT,
490490
return Args[0];
491491
}
492492

493+
static GenericValue pre_execute_typed_ptrcast(FunctionType* FT, ArrayRef<GenericValue> Args, AttributeList Attrs) {
494+
return Args[0];
495+
}
496+
493497
static GenericValue assertEqualImpl(FunctionType *FT,
494498
ArrayRef<GenericValue> Args, AttributeList Attrs)
495499
{
@@ -524,6 +528,8 @@ static void* LazyFunctionCreator(const std::string& funcName)
524528
return (void*)(void(*)())pre_execute_virtualcast;
525529
if (strncmp(funcName.c_str(), "llvm.cheerp.upcast.", strlen("llvm.cheerp.upcast."))==0)
526530
return (void*)(void(*)())pre_execute_upcast;
531+
if (strncmp(funcName.c_str(), "llvm.cheerp.typed.ptrcast.", strlen("llvm.cheerp.typed.ptrcast."))==0)
532+
return (void*)(void(*)())pre_execute_typed_ptrcast;
527533
if (strncmp(funcName.c_str(), "llvm.cheerp.allocate.array.", strlen("llvm.cheerp.allocate.array."))==0)
528534
return (void*)(void(*)())pre_execute_allocate_array;
529535
if (strncmp(funcName.c_str(), "llvm.cheerp.allocate.", strlen("llvm.cheerp.allocate."))==0)

0 commit comments

Comments
 (0)