Skip to content

Instantly share code, notes, and snippets.

@quantumsheep
Last active April 20, 2020 11:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save quantumsheep/bab733c49b7475d5cee1c45faa816a50 to your computer and use it in GitHub Desktop.
Save quantumsheep/bab733c49b7475d5cee1c45faa816a50 to your computer and use it in GitHub Desktop.
Compare LLVM IR Types. Implementation based on cmpTypes function from llvm/lib/Transforms/Utils/FunctionComparator.cpp.
#include <llvm/IR/DerivedTypes.h>
#include <llvm/Transforms/Utils/FunctionComparator.h>
bool equals(const llvm::Type *left, const llvm::Type *right)
{
auto left_ptr = llvm::dyn_cast<llvm::PointerType>(left);
auto right_ptr = llvm::dyn_cast<llvm::PointerType>(right);
if (left == right)
return true;
if (left->getTypeID() == right->getTypeID())
return true;
switch (left->getTypeID())
{
case llvm::Type::IntegerTyID:
return llvm::cast<llvm::IntegerType>(left)->getBitWidth() == llvm::cast<llvm::IntegerType>(right)->getBitWidth();
// left == right would have returned true earlier, because types are uniqued.
case llvm::Type::VoidTyID:
case llvm::Type::FloatTyID:
case llvm::Type::DoubleTyID:
case llvm::Type::X86_FP80TyID:
case llvm::Type::FP128TyID:
case llvm::Type::PPC_FP128TyID:
case llvm::Type::LabelTyID:
case llvm::Type::MetadataTyID:
case llvm::Type::TokenTyID:
return true;
case llvm::Type::PointerTyID:
assert(left_ptr && right_ptr && "Both types must be pointers here.");
return left_ptr->getAddressSpace() == right_ptr->getAddressSpace();
case llvm::Type::StructTyID:
{
auto left_struct = llvm::cast<llvm::StructType>(left);
auto right_struct = llvm::cast<llvm::StructType>(right);
if (left_struct->getNumElements() != right_struct->getNumElements())
return false;
if (left_struct->isPacked() != right_struct->isPacked())
return false;
for (unsigned i = 0, e = left_struct->getNumElements(); i != e; ++i)
{
if (!equals(left_struct->getElementType(i), right_struct->getElementType(i)))
return false;
}
return true;
}
case llvm::Type::FunctionTyID:
{
auto left_function = llvm::cast<llvm::FunctionType>(left);
auto right_function = llvm::cast<llvm::FunctionType>(right);
if (left_function->getNumParams() != right_function->getNumParams())
return false;
if (left_function->isVarArg() != right_function->isVarArg())
return false;
if (!equals(left_function->getReturnType(), right_function->getReturnType()))
return false;
for (unsigned i = 0, e = left_function->getNumParams(); i != e; ++i)
{
if (!equals(left_function->getParamType(i), right_function->getParamType(i)))
return false;
}
return true;
}
case llvm::Type::ArrayTyID:
case llvm::Type::VectorTyID:
{
auto left_sequential = llvm::cast<llvm::SequentialType>(left);
auto right_sequential = llvm::cast<llvm::SequentialType>(right);
if (left_sequential->getNumElements() != right_sequential->getNumElements())
return false;
return equals(left_sequential->getElementType(), right_sequential->getElementType());
}
default:
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment