Migrate Clift users to CDataModel

This commit is contained in:
Lauri Vasama
2026-05-04 10:49:03 +03:00
parent dd4e452f96
commit 04fe27b8e9
23 changed files with 136 additions and 162 deletions
+2 -4
View File
@@ -9,8 +9,6 @@
#include "revng/Clift/Clift.h"
#include "revng/PTML/CTokenEmitter.h"
#include "revng/Support/CTarget.h"
#include "revng/Support/CDataModel.h"
void decompile(clift::FunctionOp Function,
ptml::CTokenEmitter &Emitter,
const TargetCImplementation &Target);
void decompile(clift::FunctionOp Function, ptml::CTokenEmitter &Emitter);
+4 -5
View File
@@ -7,7 +7,7 @@
#include "revng/Clift/Clift.h"
#include "revng/PTML/CDoxygenEmitter.h"
#include "revng/PTML/CTokenEmitter.h"
#include "revng/Support/CTarget.h"
#include "revng/Support/CDataModel.h"
template<typename Type>
concept EntityWithComment = requires(Type const &Value) {
@@ -20,12 +20,11 @@ protected:
using CTE = ptml::CTokenEmitter;
ptml::CTokenEmitter &Tokens;
const TargetCImplementation &Target;
const CDataModel &DataModel;
public:
explicit CEmitter(ptml::CTokenEmitter &Emitter,
const TargetCImplementation &Target) :
Tokens(Emitter), Target(Target) {}
explicit CEmitter(ptml::CTokenEmitter &Emitter, const CDataModel &DataModel) :
Tokens(Emitter), DataModel(DataModel) {}
//===------------------------------- Types ------------------------------===//
+2 -3
View File
@@ -5,9 +5,8 @@
//
#include "revng/Clift/Clift.h"
#include "revng/Support/CTarget.h"
#include "revng/Support/CDataModel.h"
// TODO: does this really belong with the emitters?
mlir::LogicalResult verifyCSemantics(mlir::ModuleOp Module,
const TargetCImplementation &Target);
mlir::LogicalResult verifyCSemantics(mlir::ModuleOp Module);
-2
View File
@@ -10,10 +10,8 @@
#include "revng/PTML/CTokenEmitter.h"
void emitTypeAndGlobalHeader(ptml::CTokenEmitter &Tokens,
const TargetCImplementation &Target,
mlir::ModuleOp Module,
TypeEmitterConfiguration Configuration);
void emitHelperHeader(ptml::CTokenEmitter &Tokens,
const TargetCImplementation &Target,
llvm::ArrayRef<mlir::ModuleOp> Modules);
@@ -18,9 +18,9 @@ private:
public:
explicit TypeDefinitionEmitter(ptml::CTokenEmitter &Tokens,
const TargetCImplementation &Target,
const CDataModel &DataModel,
TypeEmitterConfiguration Configuration) :
CEmitter(Tokens, Target), Configuration(Configuration) {}
CEmitter(Tokens, DataModel), Configuration(Configuration) {}
private:
void emitTypeKeyword(clift::DefinedType Type);
+1 -3
View File
@@ -5,11 +5,9 @@
//
#include "revng/Clift/Clift.h"
#include "revng/Support/CTarget.h"
namespace clift {
mlir::LogicalResult legalizeForC(clift::FunctionOp Function,
const TargetCImplementation &Target);
mlir::LogicalResult legalizeForC(clift::FunctionOp Function);
} // namespace clift
+1 -3
View File
@@ -7,7 +7,6 @@
#include "mlir/Pass/Pass.h"
#include "revng/Clift/Clift.h"
#include "revng/Support/CTarget.h"
namespace clift {
@@ -29,8 +28,7 @@ PassPtr<clift::FunctionOp> createEmitFieldAccessesPass();
PassPtr<clift::FunctionOp> createTerminalBranchComplementHoistingPass();
PassPtr<clift::FunctionOp>
createCLegalizationPass(const TargetCImplementation &Target);
PassPtr<clift::FunctionOp> createCLegalizationPass();
PassPtr<clift::FunctionOp> createImmediateRadixDeductionPass();
+1 -3
View File
@@ -58,9 +58,7 @@ def CliftTerminalBranchComplementHoisting
def CliftCLegalization : Clift_Pass<"c-legalization", "clift::FunctionOp"> {
let summary = "Legalize the input for emitting C code.";
// Use the default target C implementation for clift-opt:
let constructor = "clift::createCLegalizationPass(TargetCImplementation::Default)";
let constructor = "clift::createCLegalizationPass()";
}
def CliftImmediateRadixDeduction : Clift_Pass<"deduce-immediate-radices",
@@ -13,12 +13,14 @@ inline uint64_t getExplicitPointerSize(const model::Binary &Model) {
if (Model.Architecture() == model::Architecture::Invalid)
return 0;
uint64_t PointerSize = getPointerSize(Model.Architecture());
uint64_t BinaryPointerSize = getPointerSize(Model.Architecture());
uint64_t TargetPointerSize = getPointerSize(getArchitecture(Model
.targetABI()));
// Currently we hardcode the target pointer size as 8 (64-bit), so there is
// no reason to emit explicit pointer sizes for binaries with matching size.
if (PointerSize == 8)
// If the binary and target pointer sizes match, there is no need to emit
// explicit pointer sizes.
if (BinaryPointerSize == TargetPointerSize)
return 0;
return PointerSize;
return TargetPointerSize;
}
+2 -2
View File
@@ -11,7 +11,7 @@
#include "revng/PTML/Constants.h"
#include "revng/PTML/PTMLEmitter.h"
#include "revng/Support/CTarget.h"
#include "revng/Support/CDataModel.h"
namespace ptml {
@@ -194,7 +194,7 @@ public:
struct IntegerSuffix {
bool Unsigned;
CIntegerKind MinimumType;
CStandardType MinimumType;
};
/// \pre \param Radix must be one of 2, 8, 10 or 16.
+10 -12
View File
@@ -75,7 +75,7 @@ public:
void emitIntegerLiteral(uint64_t Value,
bool IsSigned,
CIntegerKind CKind,
CStandardType Type,
unsigned Radix) {
if (IsSigned and static_cast<int64_t>(Value) < 0) {
Tokens.emitOperator(ptml::CTokenEmitter::Operator::Minus);
@@ -84,7 +84,7 @@ public:
Tokens.emitIntegerLiteral(llvm::APInt(64, Value, IsSigned),
CTE::IntegerSuffix{ .Unsigned = not IsSigned,
.MinimumType = CKind },
.MinimumType = Type },
Radix);
}
@@ -123,7 +123,7 @@ public:
Radix = mlir::cast<mlir::IntegerAttr>(Attr).getValue().getZExtValue();
auto IntType = mlir::cast<IntegerType>(Type);
auto CKind = CIntegerKind::Int;
auto CType = CStandardType::Int;
// Using any specific integer suffix is only required when the value is not
// immediately converted to another integer type. While such casts are
@@ -132,12 +132,12 @@ public:
auto Cast = getOnlyUser<CastOpInterface>(V);
if (not Cast
or not unwrapped_isa<IntegralType>(Cast.getResult().getType())) {
auto K = Target.getIntegerKind(IntType.getSize());
revng_assert(K, "Integer immediate not representable in C.");
CKind = *K;
auto Range = DataModel.getStandardIntegerRange(IntType.getSize());
revng_assert(Range, "Integer immediate not representable in C.");
CType = Range->first;
}
emitIntegerLiteral(E.getValue(), IntType.isSigned(), CKind, Radix);
emitIntegerLiteral(E.getValue(), IntType.isSigned(), CType, Radix);
rc_return;
}
@@ -983,7 +983,7 @@ public:
Parent.emitCStyleCast(Type);
}
Parent.emitIntegerLiteral(Value, IsSigned, CIntegerKind::Int, Radix);
Parent.emitIntegerLiteral(Value, IsSigned, CStandardType::Int, Radix);
}
private:
@@ -1279,8 +1279,6 @@ public:
} // namespace
void decompile(FunctionOp Function,
ptml::CTokenEmitter &Emitter,
const TargetCImplementation &Target) {
CliftToCEmitter(Emitter, Target).emitFunction(Function);
void decompile(FunctionOp Function, ptml::CTokenEmitter &Emitter) {
CliftToCEmitter(Emitter, getDataModel(Function)).emitFunction(Function);
}
+6 -14
View File
@@ -46,10 +46,12 @@ struct CEmissionPass : BaseT<CEmissionPass<BaseT, Impl>> {
if (not File)
return Base::signalPassFailure();
mlir::ModuleOp Module = Base::getOperation();
auto Tagging = static_cast<ptml::Tagging>(Base::EmitTags.getValue());
ptml::CTokenEmitter Emitter(File->os(), Tagging);
if (not std::invoke(Impl, Base::getOperation(), Emitter))
if (not Impl(Module, Emitter))
return Base::signalPassFailure();
}
};
@@ -59,11 +61,9 @@ struct CEmissionPass : BaseT<CEmissionPass<BaseT, Impl>> {
clift::PassPtr<mlir::ModuleOp> clift::createEmitCPass() {
static constexpr auto Impl = [](mlir::ModuleOp Module,
ptml::CTokenEmitter &Emitter) {
const auto &Target = TargetCImplementation::Default;
Module->walk([&Emitter](clift::FunctionOp Function) {
if (not Function.isExternal())
decompile(Function, Emitter, Target);
decompile(Function, Emitter);
});
return true;
@@ -84,11 +84,7 @@ clift::PassPtr<mlir::ModuleOp> clift::createEmitTypeAndGlobalHeaderPass() {
.ExplicitPadding = true,
};
// TODO: select target properly
const auto &Target = TargetCImplementation::Default;
emitTypeAndGlobalHeader(Tokens, Target, Module, Configuration);
emitTypeAndGlobalHeader(Tokens, Module, Configuration);
return true;
};
@@ -101,11 +97,7 @@ using HHBase = clift::impl::CliftEmitHelperHeaderBase<T>;
clift::PassPtr<mlir::ModuleOp> clift::createEmitHelperHeaderPass() {
static constexpr auto Impl = [](mlir::ModuleOp Module,
ptml::CTokenEmitter &Tokens) {
// TODO: select target properly
const auto &Target = TargetCImplementation::Default;
emitHelperHeader(Tokens, Target, { Module });
emitHelperHeader(Tokens, { Module });
return true;
};
+1 -1
View File
@@ -158,7 +158,7 @@ private:
Parent.emitPrimitiveType(T);
NeedSpace = true;
} else if (auto T = mlir::dyn_cast<PointerType>(Type)) {
if (T.getPointerSize() == Parent.Target.PointerSize) {
if (T.getPointerSize() == Parent.DataModel.PointerSize) {
Item.Kind = StackItemKind::Pointer;
Type = T.getPointeeType();
} else {
+13 -13
View File
@@ -32,12 +32,12 @@ static clift::PointerType getPointerOperationType(mlir::Operation *Op) {
}
class CVerifier : public ModuleVisitor<CVerifier> {
public:
explicit CVerifier(const TargetCImplementation &Target) : Target(Target) {}
std::optional<CDataModel> DataModel;
public:
mlir::LogicalResult visitNestedOp(mlir::Operation *Op) {
if (auto T = getPointerOperationType(Op)) {
if (T.getPointerSize() != Target.PointerSize)
if (T.getPointerSize() != DataModel->PointerSize)
return getCurrentOp()->emitOpError() << "Pointer operation is not "
"representable in the target "
"implementation.";
@@ -65,6 +65,11 @@ public:
return mlir::success();
}
mlir::LogicalResult visitModuleOp(mlir::ModuleOp Op) {
DataModel = getDataModel(Op);
return mlir::success();
}
private:
static bool isPromotingOp(mlir::Operation *Op) {
return mlir::isa<NegOp,
@@ -94,25 +99,20 @@ private:
}
bool isPotentiallyPromotingType(mlir::Type Type) {
if (auto IntType = clift::unwrapped_dyn_cast<IntegerType>(Type)) {
auto Integer = Target.getIntegerKind(IntType.getSize());
return not Integer or *Integer < CIntegerKind::Int;
}
if (auto IntType = clift::unwrapped_dyn_cast<IntegerType>(Type))
return IntType.getSize() < DataModel->getIntSize();
return false;
}
bool isCanonicalBooleanType(mlir::Type Type) {
if (auto IntType = clift::unwrapped_dyn_cast<IntegerType>(Type))
return Target.getIntegerKind(IntType.getSize()) == CIntegerKind::Int;
return IntType.getSize() == DataModel->getIntSize();
return false;
}
const TargetCImplementation &Target;
};
} // namespace
mlir::LogicalResult verifyCSemantics(mlir::ModuleOp Module,
const TargetCImplementation &Target) {
return CVerifier::visit(Module, Target);
mlir::LogicalResult verifyCSemantics(mlir::ModuleOp Module) {
return CVerifier::visit(Module);
}
+2 -2
View File
@@ -16,9 +16,9 @@ namespace {
struct VerifyCPass : clift::impl::CliftVerifyCBase<VerifyCPass> {
void runOnOperation() override {
const auto &Target = TargetCImplementation::Default;
mlir::ModuleOp Module = getOperation();
if (mlir::failed(verifyCSemantics(getOperation(), Target)))
if (mlir::failed(verifyCSemantics(Module)))
signalPassFailure();
}
};
+14 -8
View File
@@ -17,9 +17,9 @@ class CHeaderEmitterImpl : TypeDefinitionEmitter {
public:
explicit CHeaderEmitterImpl(ptml::CTokenEmitter &Tokens,
const TargetCImplementation &Target,
const CDataModel &DataModel,
TypeEmitterConfiguration Configuration) :
TypeDefinitionEmitter(Tokens, Target, Configuration) {}
TypeDefinitionEmitter(Tokens, DataModel, Configuration) {}
public:
void emitHeaderPrologue() {
@@ -135,8 +135,6 @@ public:
public:
void emitHelpers(llvm::ArrayRef<mlir::ModuleOp> Modules) {
revng_check(not Modules.empty());
// TODO: emit `#include`s
auto Graph = TypeDependencyGraph::makeHelperGraph(Modules);
@@ -179,10 +177,11 @@ public:
};
void emitTypeAndGlobalHeader(ptml::CTokenEmitter &Tokens,
const TargetCImplementation &Target,
mlir::ModuleOp Module,
TypeEmitterConfiguration Configuration) {
CHeaderEmitterImpl Emitter(Tokens, Target, Configuration);
CHeaderEmitterImpl Emitter(Tokens,
clift::getDataModel(Module),
Configuration);
Emitter.emitHeaderPrologue();
Emitter.emitCommonIncludes();
@@ -195,13 +194,20 @@ void emitTypeAndGlobalHeader(ptml::CTokenEmitter &Tokens,
}
void emitHelperHeader(ptml::CTokenEmitter &Tokens,
const TargetCImplementation &Target,
llvm::ArrayRef<mlir::ModuleOp> Modules) {
revng_check(not Modules.empty());
const CDataModel &DataModel = clift::getDataModel(Modules.front());
revng_assert(llvm::all_of(Modules.drop_front(),
[&DataModel](mlir::ModuleOp Module) {
return clift::getDataModel(Module) == DataModel;
}));
TypeEmitterConfiguration Configuration = {
.ExplicitPadding = true,
};
CHeaderEmitterImpl Emitter(Tokens, Target, Configuration);
CHeaderEmitterImpl Emitter(Tokens, DataModel, Configuration);
Emitter.emitHeaderPrologue();
Emitter.emitHelpers(Modules);
+1 -1
View File
@@ -273,7 +273,7 @@ void TypeDefinitionEmitter::emitEnumDefinition(clift::EnumType Enum) {
Tokens.emitIntegerLiteral(llvm::APInt{ 64, Value },
ptml::CTokenEmitter::IntegerSuffix{
.Unsigned = true,
.MinimumType = CIntegerKind::Int,
.MinimumType = CStandardType::Int,
},
16);
+8 -12
View File
@@ -36,12 +36,10 @@ public:
void run(pipeline::ExecutionContext &EC,
const pipes::CliftFunctionContainer &CliftFunctionContainer,
pipes::DecompileStringMap &DecompiledFunctionsContainer) {
const auto &Target = TargetCImplementation::Default;
mlir::ModuleOp Module = CliftFunctionContainer.getModule();
const auto &Model = *revng::getModelFromContext(EC);
revng_assert(verifyCSemantics(Module, Target).succeeded());
const auto &Model = *revng::getModelFromContext(EC);
revng_assert(verifyCSemantics(Module).succeeded());
std::unordered_map<MetaAddress, clift::FunctionOp> Functions;
Module->walk([&](clift::FunctionOp F) {
@@ -62,7 +60,7 @@ public:
{
llvm::raw_string_ostream OS(Code);
ptml::CTokenEmitter Emitter(OS, ptml::Tagging::Enabled);
decompile(It->second, Emitter, Target);
decompile(It->second, Emitter);
}
DecompiledFunctionsContainer.insert_or_assign(Function.Entry(),
@@ -88,18 +86,16 @@ EmitC::EmitC(const Model &Model,
void EmitC::runOnFunction(const model::Function &Function) {
using namespace clift;
const auto &Target = TargetCImplementation::Default;
ObjectID Object(Function.Entry());
mlir::ModuleOp Module = Input.getModule(Object);
revng_assert(verifyCSemantics(Module, Target).succeeded());
revng_assert(verifyCSemantics(Module).succeeded());
FunctionOp MLIRFunction = getUniqueIsolatedFunction(Module, Function.Entry());
{
auto OS = Output.getOStream(Object);
ptml::CTokenEmitter Emitter(*OS, ptml::Tagging::Enabled);
decompile(MLIRFunction, Emitter, Target);
}
auto OS = Output.getOStream(Object);
ptml::CTokenEmitter Emitter(*OS, ptml::Tagging::Enabled);
decompile(MLIRFunction, Emitter);
}
} // namespace revng::pypeline::piperuns
+1 -1
View File
@@ -100,7 +100,7 @@ struct TargetOptimizationPipe {
static constexpr auto Name = "clift-target-optimization";
static void configurePassManager(mlir::PassManager &PM) {
PM.addPass(clift::createCLegalizationPass(TargetCImplementation::Default));
PM.addPass(clift::createCLegalizationPass());
PM.addPass(clift::createImmediateRadixDeductionPass());
}
};
+46 -61
View File
@@ -6,6 +6,7 @@
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
#include "revng/Clift/CliftOpHelpers.h"
#include "revng/CliftTransforms/Expressions.h"
#include "revng/CliftTransforms/Legalization.h"
#include "revng/CliftTransforms/Passes.h"
@@ -19,19 +20,10 @@ using namespace clift;
namespace {
static IntegerType getIntType(mlir::MLIRContext *Context,
const TargetCImplementation &Target) {
return IntegerType::get(Context, IntegerKind::Signed, Target.getIntSize());
const CDataModel &DataModel) {
return IntegerType::get(Context, IntegerKind::Signed, DataModel.getIntSize());
}
struct TargetInfo {
const TargetCImplementation &Target;
IntegerType IntType;
explicit TargetInfo(mlir::MLIRContext *Context,
const TargetCImplementation &Target) :
Target(Target), IntType(getIntType(Context, Target)) {}
};
static mlir::OpOperand &getOnlyUse(mlir::Value Value) {
revng_assert(Value.hasOneUse());
return *Value.use_begin();
@@ -104,9 +96,9 @@ struct PointerResizePattern : mlir::OpRewritePattern<OpT> {
uint64_t TargetPointerSize;
explicit PointerResizePattern(mlir::MLIRContext *Context,
const TargetInfo &Target) :
const CDataModel &DataModel) :
mlir::OpRewritePattern<OpT>(Context),
TargetPointerSize(Target.Target.PointerSize) {}
TargetPointerSize(DataModel.PointerSize) {}
clift::PointerType
makeTargetPointerType(clift::PointerType OldPointerType) const {
@@ -256,9 +248,9 @@ struct BooleanCanonicalizationPattern
IntegerType IntType;
explicit BooleanCanonicalizationPattern(mlir::MLIRContext *Context,
const TargetInfo &Target) :
const CDataModel &DataModel) :
mlir::OpTraitRewritePattern<clift::ReturnsBoolean>(Context),
IntType(Target.IntType) {}
IntType(getIntType(Context, DataModel)) {}
mlir::LogicalResult
matchAndRewrite(mlir::Operation *Op,
@@ -281,8 +273,9 @@ struct ArithmeticPromotionPattern : mlir::OpRewritePattern<OpT> {
IntegerType IntType;
explicit ArithmeticPromotionPattern(mlir::MLIRContext *Context,
const TargetInfo &Target) :
mlir::OpRewritePattern<OpT>(Context), IntType(Target.IntType) {}
const CDataModel &DataModel) :
mlir::OpRewritePattern<OpT>(Context),
IntType(getIntType(Context, DataModel)) {}
mlir::LogicalResult tryPromoteTypes(mlir::PatternRewriter &Rewriter,
clift::ExpressionOpInterface Op,
@@ -335,14 +328,11 @@ struct ShiftPromotionPattern : ArithmeticPromotionPattern<OpT> {
// * 0 -> (my_enum)0, where the original expression has type my_enum and my_enum
// does not have an enumerator with a value of 0.
struct ImmediateCastPattern : mlir::OpRewritePattern<ImmediateOp> {
const TargetCImplementation &Target;
uint64_t IntSize;
const CDataModel &DataModel;
explicit ImmediateCastPattern(mlir::MLIRContext *Context,
const TargetInfo &Target) :
mlir::OpRewritePattern<ImmediateOp>(Context),
Target(Target.Target),
IntSize(Target.IntType.getSize()) {}
const CDataModel &DataModel) :
mlir::OpRewritePattern<ImmediateOp>(Context), DataModel(DataModel) {}
mlir::LogicalResult rewriteWithCast(ImmediateOp Op,
mlir::Type NewImmediateType,
@@ -370,8 +360,8 @@ struct ImmediateCastPattern : mlir::OpRewritePattern<ImmediateOp> {
}
bool isRepresentableLiteralSize(uint64_t Size) const {
auto C = Target.getIntegerKind(Size);
return C and CIntegerKind::Int <= *C and *C <= CIntegerKind::LongLong;
auto Range = DataModel.getStandardIntegerRange(Size);
return Range and Range->second >= CStandardType::Int;
}
mlir::LogicalResult
@@ -382,7 +372,9 @@ struct ImmediateCastPattern : mlir::OpRewritePattern<ImmediateOp> {
return mlir::failure();
// Sizes in the range [sizeof(int), 8] must be representable in the target.
uint64_t NewSize = std::clamp<uint64_t>(Type.getSize(), IntSize, 8);
uint64_t NewSize = std::clamp<uint64_t>(Type.getSize(),
DataModel.getIntSize(),
8);
revng_assert(NewSize != Type.getSize());
revng_assert(isRepresentableLiteralSize(NewSize));
@@ -414,62 +406,55 @@ struct ImmediateCastPattern : mlir::OpRewritePattern<ImmediateOp> {
struct CLegalizationPass
: clift::impl::CliftCLegalizationBase<CLegalizationPass> {
const TargetCImplementation &Target;
explicit CLegalizationPass(const TargetCImplementation &Target) :
Target(Target) {}
void runOnOperation() override {
if (legalizeForC(getOperation(), Target).failed())
if (legalizeForC(getOperation()).failed())
signalPassFailure();
}
};
} // namespace
mlir::LogicalResult clift::legalizeForC(clift::FunctionOp Function,
const TargetCImplementation &Target) {
mlir::LogicalResult clift::legalizeForC(clift::FunctionOp Function) {
mlir::MLIRContext *Context = Function.getContext();
mlir::RewritePatternSet Set(Context);
TargetInfo T(Context, Target);
const CDataModel &DataModel = getDataModel(Function);
// Pointer resizing
Set.add<ResizePtrAddPattern>(Context, T);
Set.add<ResizePtrSubPattern>(Context, T);
Set.add<ResizePtrDiffPattern>(Context, T);
Set.add<PointerResizePattern<IndirectionOp>>(Context, T);
Set.add<PointerResizePattern<SubscriptOp>>(Context, T);
Set.add<PointerResizePattern<AccessOp>>(Context, T);
Set.add<PointerResizePattern<CallOp>>(Context, T);
Set.add<ResizeAddressofPattern>(Context, T);
Set.add<ResizeDecayCastPattern>(Context, T);
Set.add<ResizePtrAddPattern>(Context, DataModel);
Set.add<ResizePtrSubPattern>(Context, DataModel);
Set.add<ResizePtrDiffPattern>(Context, DataModel);
Set.add<PointerResizePattern<IndirectionOp>>(Context, DataModel);
Set.add<PointerResizePattern<SubscriptOp>>(Context, DataModel);
Set.add<PointerResizePattern<AccessOp>>(Context, DataModel);
Set.add<PointerResizePattern<CallOp>>(Context, DataModel);
Set.add<ResizeAddressofPattern>(Context, DataModel);
Set.add<ResizeDecayCastPattern>(Context, DataModel);
// Boolean canonicalization
Set.add<BooleanCanonicalizationPattern>(Context, T);
Set.add<BooleanCanonicalizationPattern>(Context, DataModel);
// Integer promotion
Set.add<ArithmeticPromotionPattern<NegOp>>(Context, T);
Set.add<ArithmeticPromotionPattern<AddOp>>(Context, T);
Set.add<ArithmeticPromotionPattern<SubOp>>(Context, T);
Set.add<ArithmeticPromotionPattern<MulOp>>(Context, T);
Set.add<ArithmeticPromotionPattern<DivOp>>(Context, T);
Set.add<ArithmeticPromotionPattern<RemOp>>(Context, T);
Set.add<ArithmeticPromotionPattern<BitwiseNotOp>>(Context, T);
Set.add<ArithmeticPromotionPattern<BitwiseAndOp>>(Context, T);
Set.add<ArithmeticPromotionPattern<BitwiseOrOp>>(Context, T);
Set.add<ArithmeticPromotionPattern<BitwiseXorOp>>(Context, T);
Set.add<ShiftPromotionPattern<ShiftLeftOp>>(Context, T);
Set.add<ShiftPromotionPattern<ShiftRightOp>>(Context, T);
Set.add<ArithmeticPromotionPattern<NegOp>>(Context, DataModel);
Set.add<ArithmeticPromotionPattern<AddOp>>(Context, DataModel);
Set.add<ArithmeticPromotionPattern<SubOp>>(Context, DataModel);
Set.add<ArithmeticPromotionPattern<MulOp>>(Context, DataModel);
Set.add<ArithmeticPromotionPattern<DivOp>>(Context, DataModel);
Set.add<ArithmeticPromotionPattern<RemOp>>(Context, DataModel);
Set.add<ArithmeticPromotionPattern<BitwiseNotOp>>(Context, DataModel);
Set.add<ArithmeticPromotionPattern<BitwiseAndOp>>(Context, DataModel);
Set.add<ArithmeticPromotionPattern<BitwiseOrOp>>(Context, DataModel);
Set.add<ArithmeticPromotionPattern<BitwiseXorOp>>(Context, DataModel);
Set.add<ShiftPromotionPattern<ShiftLeftOp>>(Context, DataModel);
Set.add<ShiftPromotionPattern<ShiftRightOp>>(Context, DataModel);
// Literal typing
Set.add<ImmediateCastPattern>(Context, T);
Set.add<ImmediateCastPattern>(Context, DataModel);
auto Patterns = mlir::FrozenRewritePatternSet(std::move(Set));
return mlir::applyPatternsAndFoldGreedily(Function, Patterns);
}
clift::PassPtr<clift::FunctionOp>
clift::createCLegalizationPass(const TargetCImplementation &Target) {
return std::make_unique<CLegalizationPass>(Target);
clift::PassPtr<clift::FunctionOp> clift::createCLegalizationPass() {
return std::make_unique<CLegalizationPass>();
}
+4 -3
View File
@@ -69,11 +69,11 @@ static llvm::StringRef
getCIntegerLiteralSuffix(const ptml::CTokenEmitter::IntegerSuffix &Suffix) {
switch (Suffix.MinimumType) {
default:
case CIntegerKind::Int:
case CStandardType::Int:
return Suffix.Unsigned ? "U" : "";
case CIntegerKind::Long:
case CStandardType::Long:
return Suffix.Unsigned ? "UL" : "L";
case CIntegerKind::LongLong:
case CStandardType::LongLong:
return Suffix.Unsigned ? "ULL" : "LL";
}
}
@@ -593,6 +593,7 @@ static bool isRadixSupported(uint64_t Radix) {
void CTokenEmitter::emitIntegerLiteral(llvm::APInt Value,
std::optional<IntegerSuffix> Suffix,
uint64_t Radix) {
revng_assert(not Suffix or isIntegerType(Suffix->MinimumType));
revng_assert(not IsEmittingComment,
"Cannot emit tokens while an open CommentEmitter exists.");
@@ -43,13 +43,13 @@ module attributes {clift.module} {
clift.yield %u : !uint32_t
}
// CHECK: 0LL;
// CHECK: 0L;
clift.expr {
%0 = clift.imm 0 : !int64_t
clift.yield %0 : !int64_t
}
// CHECK: 0ULL;
// CHECK: 0UL;
clift.expr {
%0 = clift.imm 0 : !uint64_t
clift.yield %0 : !uint64_t
+6
View File
@@ -18,10 +18,16 @@ using namespace llvm::cl;
static constexpr char ToolName[] = "Standalone optimizer driver\n";
static void initializeCliftDialect(mlir::MLIRContext *Context,
clift::CliftDialect *Dialect) {
Dialect->setDefaultDataModel(CDataModel::getDefaultDataModel(8));
}
int main(int Argc, char *Argv[]) {
mlir::DialectRegistry Registry;
Registry.insert<clift::CliftDialect>();
Registry.addExtension(initializeCliftDialect);
mlir::registerTransformsPasses();
clift::registerCliftPasses();