Skip to content

Commit

Permalink
improve GEP check
Browse files Browse the repository at this point in the history
adds a check to see if the GEP with more then 2 operands is done on an array, if this is the case we can compare the array and its offset directly without dereferencing it
  • Loading branch information
rvan-mee committed Aug 19, 2024
1 parent 4ed1d4d commit 480cdb6
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 3 deletions.
2 changes: 1 addition & 1 deletion llvm/lib/CheerpUtils/Utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ bool InlineableCache::isInlineableImpl(const Instruction& I)
if (IPointerKind == COMPLETE_OBJECT) {
auto type = cast<GetElementPtrInst>(I).getResultElementType();
// Always inline geps to immutable fields of a complete object.
if (TypeSupport::isImmutableType(type))
if (TypeSupport::isImmutableType(type) || getGEPContainerType(&I)->isArrayTy())
return true;

return !hasMoreThan1Use;
Expand Down
8 changes: 6 additions & 2 deletions llvm/lib/CheerpWriter/CheerpWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1640,6 +1640,11 @@ void CheerpWriter::compileEqualPointersComparison(const llvm::Value* lhs, const
else
compareString = (p == CmpInst::ICMP_NE) ? "!==" : "===";

auto canCompareAsSplitRegular = [&](POINTER_KIND kind, const llvm::Value* value) -> bool {
return (kind == REGULAR || kind == SPLIT_REGULAR || kind == RAW || kind == CONSTANT ||
(isGEP(value) && (cast<User>(value)->getNumOperands() == 2 || getGEPContainerType(cast<User>(value))->isArrayTy())));
};

if(compareRaw)
{
stream << "(";
Expand All @@ -1653,8 +1658,7 @@ void CheerpWriter::compileEqualPointersComparison(const llvm::Value* lhs, const
// NOTE: For any pointer-to-immutable, converting to CO is actually a dereference. (base[offset] in both cases)
// PA enforces that comparisons between pointers-to-immutable (which include pointers-to-pointers)
// need a SPLIT_REGULAR kind. Make sure to also use SPLIT_REGULAR if one kind is CONSTANT (e.g. null)
else if((lhsKind == REGULAR || lhsKind == SPLIT_REGULAR || lhsKind == RAW ||lhsKind == CONSTANT || (isGEP(lhs) && cast<User>(lhs)->getNumOperands()==2)) &&
(rhsKind == REGULAR || rhsKind == SPLIT_REGULAR || rhsKind == RAW ||rhsKind == CONSTANT || (isGEP(rhs) && cast<User>(rhs)->getNumOperands()==2)))
else if (canCompareAsSplitRegular(lhsKind, lhs) && canCompareAsSplitRegular(rhsKind, rhs))
{
assert(lhsKind != COMPLETE_OBJECT || !isa<Instruction>(lhs) ||
isInlineable(*cast<Instruction>(lhs), PA));
Expand Down

0 comments on commit 480cdb6

Please sign in to comment.