diff --git a/include/vast/Conversion/Passes.hpp b/include/vast/Conversion/Passes.hpp index b9474b6efc..1c2c39fcb7 100644 --- a/include/vast/Conversion/Passes.hpp +++ b/include/vast/Conversion/Passes.hpp @@ -62,6 +62,8 @@ namespace vast // ToMem std::unique_ptr< mlir::Pass > createRefsToSSAPass(); + std::unique_ptr< mlir::Pass > createEvictStaticLocalsPass(); + std::unique_ptr< mlir::Pass > createStripParamLValuesPass(); std::unique_ptr< mlir::Pass > createVarsToCellsPass(); diff --git a/include/vast/Conversion/Passes.td b/include/vast/Conversion/Passes.td index 26b7d361b0..7183076a80 100644 --- a/include/vast/Conversion/Passes.td +++ b/include/vast/Conversion/Passes.td @@ -84,6 +84,16 @@ def StripParamLValues : Pass<"vast-strip-param-lvalues", "core::ModuleOp"> { ]; } +def EvictStaticLocals : Pass<"vast-evict-static-locals", "core::ModuleOp"> { + let summary = "Evict hl.var declarations with static storage to global scope."; + + let constructor = "vast::createEvictStaticLocalsPass()"; + let dependentDialects = [ + "vast::hl::HighLevelDialect", + "vast::core::CoreDialect" + ]; +} + def VarsToCells : Pass<"vast-vars-to-cells", "core::ModuleOp"> { let summary = "Lower `hl.var` into ssa-based `ll.cell`."; diff --git a/include/vast/Dialect/Core/CoreAttributes.hpp b/include/vast/Dialect/Core/CoreAttributes.hpp index ea9fd483bd..bc2a40554e 100644 --- a/include/vast/Dialect/Core/CoreAttributes.hpp +++ b/include/vast/Dialect/Core/CoreAttributes.hpp @@ -28,4 +28,12 @@ namespace vast::core { mlir::CallInterfaceCallable get_callable_for_callee(operation op); + ParseResult parseStorageClasses( + Parser &parser, Attribute &storage_class, Attribute &thread_storage_class + ); + + void printStorageClasses( + Printer &printer, mlir::Operation *op, core::StorageClassAttr storage_class, core::TSClassAttr thread_storage_class + ); + } // namespace vast::core diff --git a/include/vast/Dialect/Core/CoreAttributes.td b/include/vast/Dialect/Core/CoreAttributes.td index 0b264d6db4..f7ea062dcc 100644 --- a/include/vast/Dialect/Core/CoreAttributes.td +++ b/include/vast/Dialect/Core/CoreAttributes.td @@ -143,4 +143,110 @@ def Core_SourceLanguageAttr : EnumAttr< Core_Dialect, Core_SourceLanguage, "lang include "vast/Dialect/Core/Linkage.td" +// +// Storage and context attributes +// + +class Core_StorageClassAttr< string name, int val > + : I64EnumAttrCase< name, val > +{} + +class Core_StorageClassList< string name, string summary, list cases > + : I64EnumAttr< name, summary, cases > +{} + +def Core_SC_None : Core_StorageClassAttr< "sc_none", 0 >; +def Core_SC_Auto : Core_StorageClassAttr< "sc_auto", 1 >; +def Core_SC_Static : Core_StorageClassAttr< "sc_static", 2 >; +def Core_SC_Extern : Core_StorageClassAttr< "sc_extern", 3 >; +def Core_SC_PrivateExtern : Core_StorageClassAttr< "sc_private_extern", 4 >; +def Core_SC_Register : Core_StorageClassAttr< "sc_register", 5 >; + +let cppNamespace = "::vast::core" in +def Core_StorageClass : Core_StorageClassList< "StorageClass", "storage class", [ + Core_SC_None, + Core_SC_Auto, + Core_SC_Static, + Core_SC_Extern, + Core_SC_PrivateExtern, + Core_SC_Register +] >; + +// thread storage class + +class Core_TSCAttr< string name, int val > : I64EnumAttrCase< name, val > {} + +class Core_TSCList< string name, string summary, list cases > + : I64EnumAttr< name, summary, cases > +{} + +def Core_TSC_None : Core_TSCAttr< "tsc_none", 0 >; +def Core_TSC_GNU_Thread : Core_TSCAttr< "tsc_gnu_thread", 1 >; +def Core_TSC_CXX_Thread : Core_TSCAttr< "tsc_cxx_thread", 2 >; +def Core_TSC_C_Thread : Core_TSCAttr< "tsc_c_thread", 3 >; + +let cppNamespace = "::vast::core" in +def Core_ThreadStorage : Core_TSCList< "TSClass", "thread storage class", +[ + Core_TSC_None, + Core_TSC_GNU_Thread, + Core_TSC_CXX_Thread, + Core_TSC_C_Thread +] >; + +// Storage Duration + +class Core_StorageDurationAttr< string name, int val > : I64EnumAttrCase< name, val > {} + +class Core_StorageDurationList< string name, string summary, list cases > + : I64EnumAttr< name, summary, cases > +{} + +def Core_SD_FullExpression : Core_StorageDurationAttr< "sd_none", 0 >; +def Core_SD_Automatic : Core_StorageDurationAttr< "sd_automatic", 1 >; +def Core_SD_Thread : Core_StorageDurationAttr< "sd_thread", 2 >; +def Core_SD_Static : Core_StorageDurationAttr< "sd_static", 3 >; +def Core_SD_Dynamic : Core_StorageDurationAttr< "sd_dynamic", 4 >; + +let cppNamespace = "::vast::core" in +def Core_StorageDuration + : Core_StorageDurationList< "StorageDuration", "storage duration", +[ + Core_SD_FullExpression, + Core_SD_Automatic, + Core_SD_Thread, + Core_SD_Static, + Core_SD_Dynamic +] >; + +// declaration context kinds +class Core_DeclContextAttr< string name, int val > : I64EnumAttrCase< name, val > {} + +class Core_DeclContextList< string name, string summary, list cases > + : I64EnumAttr< name, summary, cases > +{} + +def Core_DC_Function : Core_DeclContextAttr< "dc_function", 0 >; +def Core_DC_Method : Core_DeclContextAttr< "dc_method", 1 >; +def Core_DC_Block : Core_DeclContextAttr< "dc_block", 2 >; +def Core_DC_Capture : Core_DeclContextAttr< "dc_capture", 3 >; +def Core_DC_TranslationUnit : Core_DeclContextAttr< "dc_translation_unit", 4 >; +def Core_DC_Record : Core_DeclContextAttr< "dc_record", 5 >; +def Core_DC_Enum : Core_DeclContextAttr< "dc_enum", 6 >; +def Core_DC_Namespace : Core_DeclContextAttr< "dc_namespace", 7 >; + +let cppNamespace = "::vast::core" in +def Core_DeclContextKind + : Core_DeclContextList< "DeclContextKind", "declaration context kind", +[ + Core_DC_Function, + Core_DC_Method, + Core_DC_Block, + Core_DC_Capture, + Core_DC_TranslationUnit, + Core_DC_Record, + Core_DC_Enum, + Core_DC_Namespace +] >; + #endif // VAST_DIALECT_CORE_COREATTRIBUTES diff --git a/include/vast/Dialect/Core/Func.td b/include/vast/Dialect/Core/Func.td index 33ec007e56..ed7cbe2925 100644 --- a/include/vast/Dialect/Core/Func.td +++ b/include/vast/Dialect/Core/Func.td @@ -10,18 +10,7 @@ include "mlir/Interfaces/FunctionInterfaces.td" include "vast/Dialect/Core/Interfaces/SymbolInterface.td" include "vast/Dialect/Core/CoreTraits.td" - -def Core_GlobalLinkageKind : Attr< - CPred<"::llvm::isa<::vast::core::GlobalLinkageKindAttr>($_self)">, - "global linkage kind" -> { - let storageType = "::vast::core::GlobalLinkageKindAttr"; - let returnType = "::vast::core::GlobalLinkageKind"; - let convertFromStorage = "$_self.getValue()"; - let constBuilderCall = [{ - ::vast::core::GlobalLinkageKindAttr::get($_builder.getContext(), $0) - }]; -} +include "vast/Dialect/Core/LinkageHelper.td" def Core_FunctionType : Type< CPred<"::llvm::isa<::vast::core::FunctionType>($_self)">, diff --git a/include/vast/Dialect/Core/Interfaces/CMakeLists.txt b/include/vast/Dialect/Core/Interfaces/CMakeLists.txt index a2de145423..d6ab0139a1 100644 --- a/include/vast/Dialect/Core/Interfaces/CMakeLists.txt +++ b/include/vast/Dialect/Core/Interfaces/CMakeLists.txt @@ -1,3 +1,4 @@ +add_vast_op_interface(DeclStorageInterface) add_vast_op_interface(TypeDefinitionInterface) add_vast_op_interface(SymbolInterface) diff --git a/include/vast/Dialect/Core/Interfaces/DeclStorageInterface.hpp b/include/vast/Dialect/Core/Interfaces/DeclStorageInterface.hpp new file mode 100644 index 0000000000..b762a0c9d1 --- /dev/null +++ b/include/vast/Dialect/Core/Interfaces/DeclStorageInterface.hpp @@ -0,0 +1,20 @@ +// Copyright (c) 2024, Trail of Bits, Inc. + +#pragma once + +#include "vast/Util/Warnings.hpp" + +VAST_RELAX_WARNINGS +#include +#include +#include +#include +#include +VAST_RELAX_WARNINGS + +#include "vast/Dialect/Core/CoreOps.hpp" + +#define GET_OP_FWD_DEFINES +#include "vast/Dialect/HighLevel/HighLevel.h.inc" +/// Include the generated interface declarations. +#include "vast/Dialect/Core/Interfaces/DeclStorageInterface.h.inc" diff --git a/include/vast/Dialect/Core/Interfaces/DeclStorageInterface.td b/include/vast/Dialect/Core/Interfaces/DeclStorageInterface.td new file mode 100644 index 0000000000..06df4b0108 --- /dev/null +++ b/include/vast/Dialect/Core/Interfaces/DeclStorageInterface.td @@ -0,0 +1,124 @@ +// Copyright (c) 2024, Trail of Bits, Inc. + +#ifndef VAST_INTERFACES_DECL_STORAGE_INTERFACE +#define VAST_INTERFACES_DECL_STORAGE_INTERFACE + +include "mlir/IR/OpBase.td" +include "vast/Dialect/Core/StorageInfo.td" +include "vast/Dialect/Core/Interfaces/Common.td" + +def Core_DeclStorageInterface : Core_OpInterface< "DeclStorageInterface" > { + let description = [{ Interface for querying info about declaration storage. }]; + + let methods = [ + InterfaceMethod<"", + "bool", "hasLocalStorage", (ins), [{}], + /*defaultImplementation=*/[{ + switch ($_op.getStorageClass()) { + case ::vast::core::StorageClass::sc_none: + return !isFileVarDecl() && $_op.getThreadStorageClass() == TSClass::tsc_none; + case ::vast::core::StorageClass::sc_register: return isLocalVarDecl(); + case ::vast::core::StorageClass::sc_auto: return true; + case ::vast::core::StorageClass::sc_extern: + case ::vast::core::StorageClass::sc_static: + case ::vast::core::StorageClass::sc_private_extern: return false; + } + + VAST_UNIMPLEMENTED_MSG("unknown starage class"); + }] + >, + InterfaceMethod<"", + "bool", "isLocalVarDecl", (ins), [{}], + /*defaultImplementation=*/[{ return this->isInFunctionOrMethodContext(); }] + >, + InterfaceMethod<"", + "bool", "isStaticLocal", (ins), [{}], + /*defaultImplementation=*/[{ + if (isFileVarDecl()) + return false; + auto sc = $_op.getStorageClass(); + if (sc == ::vast::core::StorageClass::sc_static) + return true; + auto tsc = $_op.getThreadStorageClass(); + return sc == ::vast::core::StorageClass::sc_none && tsc == TSClass::tsc_cxx_thread; + }] + >, + InterfaceMethod<"", + "bool", "hasExternalStorage", (ins), [{}], + /*defaultImplementation=*/[{ + auto sc = $_op.getStorageClass(); + return sc == ::vast::core::StorageClass::sc_extern + || sc == ::vast::core::StorageClass::sc_private_extern; + }] + >, + InterfaceMethod<"", + "bool", "hasGlobalStorage", (ins), [{}], + /*defaultImplementation=*/[{ return !hasLocalStorage(); }] + >, + InterfaceMethod<"", + "::vast::core::StorageDuration", "getStorageDuration", (ins), [{}], + /*defaultImplementation=*/[{ + if (hasLocalStorage()) + return StorageDuration::sd_automatic; + if ($_op.getThreadStorageClass() != TSClass::tsc_none) + return StorageDuration::sd_thread; + return StorageDuration::sd_static; + }] + >, + InterfaceMethod<"", + "::vast::core::DeclContextKind", "getDeclContextKind", (ins), [{}], + /*defaultImplementation=*/[{ + if (auto kind_attr = $_op->template getAttrOfType< core::DeclContextKindAttr >("context")) { + return kind_attr.getValue(); + } + auto st = core::get_effective_symbol_table_for< core::var_symbol >($_op)->get_defining_operation(); + if (mlir::isa< mlir::FunctionOpInterface >(st)) + return DeclContextKind::dc_function; + if (st->template hasTrait< core::ScopeLikeTrait >()) + return DeclContextKind::dc_function; + if (mlir::isa< core::ModuleOp >(st)) + return DeclContextKind::dc_translation_unit; + if (mlir::isa< hl::StructDeclOp >(st)) + return DeclContextKind::dc_record; + if (mlir::isa< hl::EnumDeclOp >(st)) + return DeclContextKind::dc_enum; + VAST_UNIMPLEMENTED_MSG("unknown declaration context"); + }] + >, + InterfaceMethod<"", + "bool", "isStaticDataMember", (ins), [{}], + /*defaultImplementation=*/[{ return isInRecordContext(); }] + >, + InterfaceMethod<"", + "bool", "isInFileContext", (ins), [{}], + /*defaultImplementation=*/[{ + auto kind = getDeclContextKind(); + return kind == DeclContextKind::dc_translation_unit + || kind == DeclContextKind::dc_namespace; + }] + >, + InterfaceMethod<"", + "bool", "isInFunctionOrMethodContext", (ins), [{}], + /*defaultImplementation=*/[{ + auto kind = getDeclContextKind(); + return kind == DeclContextKind::dc_function + || kind == DeclContextKind::dc_method + || kind == DeclContextKind::dc_capture; + }] + >, + InterfaceMethod<"", + "bool", "isInRecordContext", (ins), [{}], + /*defaultImplementation=*/[{ + return getDeclContextKind() == DeclContextKind::dc_record; + }] + >, + InterfaceMethod<"", + "bool", "isFileVarDecl", (ins), [{}], + /*defaultImplementation=*/[{ + return isInFileContext() || isStaticDataMember(); + }] + > + ]; +} + +#endif // VAST_INTERFACES_DECL_STORAGE_INTERFACE diff --git a/include/vast/Dialect/Core/Linkage.hpp b/include/vast/Dialect/Core/Linkage.hpp index 668585c638..0c612a4052 100644 --- a/include/vast/Dialect/Core/Linkage.hpp +++ b/include/vast/Dialect/Core/Linkage.hpp @@ -6,6 +6,7 @@ VAST_RELAX_WARNINGS #include +#include VAST_UNRELAX_WARNINGS #include "vast/Dialect/HighLevel/HighLevelAttributes.hpp" @@ -21,4 +22,6 @@ namespace vast::core { std::optional< core::GlobalLinkageKind > get_function_linkage(clang::GlobalDecl glob); + mlir::LLVM::Linkage convert_linkage_to_llvm(core::GlobalLinkageKind linkage); + } // namespace vast::core diff --git a/include/vast/Dialect/Core/LinkageHelper.td b/include/vast/Dialect/Core/LinkageHelper.td new file mode 100644 index 0000000000..23f3e8737f --- /dev/null +++ b/include/vast/Dialect/Core/LinkageHelper.td @@ -0,0 +1,19 @@ +// Copyright (c) 2023, Trail of Bits, Inc. + +#ifndef VAST_DIALECT_CORE_LINKAGE_HELPER +#define VAST_DIALECT_CORE_LINKAGE_HELPER +include "mlir/IR/OpBase.td" + +def Core_GlobalLinkageKind : Attr< + CPred<"::llvm::isa<::vast::core::GlobalLinkageKindAttr>($_self)">, + "global linkage kind" +> { + let storageType = "::vast::core::GlobalLinkageKindAttr"; + let returnType = "::vast::core::GlobalLinkageKind"; + let convertFromStorage = "$_self.getValue()"; + let constBuilderCall = [{ + ::vast::core::GlobalLinkageKindAttr::get($_builder.getContext(), $0) + }]; +} + +#endif // VAST_DIALECT_CORE_LINKAGE_HELPER diff --git a/include/vast/Dialect/Core/StorageInfo.td b/include/vast/Dialect/Core/StorageInfo.td new file mode 100644 index 0000000000..9a0edae610 --- /dev/null +++ b/include/vast/Dialect/Core/StorageInfo.td @@ -0,0 +1,31 @@ +#ifndef VAST_DIALECT_CORE_STORAGEINFO +#define VAST_DIALECT_CORE_STORAGEINFO + +include "mlir/IR/AttrTypeBase.td" +include "mlir/IR/BuiltinAttributeInterfaces.td" + +def Core_StorageClass : Attr< + CPred<"::mlir::isa<::vast::core::StorageClassAttr>($_self)">, + "declaration storage class" +> { + let storageType = "::vast::core::StorageClassAttr"; + let returnType = "::vast::core::StorageClass"; + let convertFromStorage = "$_self.getValue()"; + let constBuilderCall = [{ + ::vast::core::StorageClassAttr::get($_builder.getContext(), $0) + }]; +} + +def Core_ThreadStorage : Attr< + CPred<"::mlir::isa<::vast::core::TSClassAttr>($_self)">, + "declaration storage class" +> { + let storageType = "::vast::core::TSClassAttr"; + let returnType = "::vast::core::TSClass"; + let convertFromStorage = "$_self.getValue()"; + let constBuilderCall = [{ + ::vast::core::TSClassAttr::get($_builder.getContext(), $0) + }]; +} + +#endif //VAST_DIALECT_CORE_STORAGEINFO diff --git a/include/vast/Dialect/HighLevel/HighLevelOps.hpp b/include/vast/Dialect/HighLevel/HighLevelOps.hpp index ebb478fd0e..85bff6e749 100644 --- a/include/vast/Dialect/HighLevel/HighLevelOps.hpp +++ b/include/vast/Dialect/HighLevel/HighLevelOps.hpp @@ -24,6 +24,7 @@ VAST_UNRELAX_WARNINGS #include "vast/Interfaces/TypeTraitExprInterface.hpp" #include "vast/Interfaces/AST/DeclInterface.hpp" +#include "vast/Dialect/Core/Interfaces/DeclStorageInterface.hpp" #define GET_OP_CLASSES #include "vast/Dialect/HighLevel/HighLevel.h.inc" @@ -31,13 +32,4 @@ VAST_UNRELAX_WARNINGS namespace vast::hl { FuncOp getCallee(CallOp call); - - ParseResult parseStorageClasses( - Parser &parser, Attribute &storage_class, Attribute &thread_storage_class - ); - - void printStorageClasses( - Printer &printer, mlir::Operation *op, StorageClassAttr storage_class, TSClassAttr thread_storage_class - ); - } // namespace vast::hl diff --git a/include/vast/Dialect/HighLevel/HighLevelOps.td b/include/vast/Dialect/HighLevel/HighLevelOps.td index 2c6550737e..c426d9d6e1 100644 --- a/include/vast/Dialect/HighLevel/HighLevelOps.td +++ b/include/vast/Dialect/HighLevel/HighLevelOps.td @@ -452,7 +452,7 @@ def HighLevel_ReturnOp def HighLevel_DeclRefOp : HighLevel_Op< "ref" > , Arguments<(ins FlatSymbolRefAttr:$name)> - , Results<(outs HighLevel_LValueOf:$result)> + , Results<(outs AnyType:$result)> { let summary = "VAST variable reference declaration"; let description = [{ VAST variable reference declaration }]; @@ -471,17 +471,6 @@ def HighLevel_FuncRefOp let assemblyFormat = "$function attr-dict `:` type($result)"; } -def HighLevel_GlobalRefOp - : HighLevel_Op< "globref" > - , Arguments<(ins FlatSymbolRefAttr:$global)> - , Results<(outs AnyType:$result)> -{ - let summary = "VAST global variable reference declaration"; - let description = [{ VAST global variable reference declaration }]; - - let assemblyFormat = "$global attr-dict `:` type($result)"; -} - def HighLevel_EnumRefOp : HighLevel_Op< "enumref" > , Arguments<(ins FlatSymbolRefAttr:$value)> diff --git a/include/vast/Dialect/HighLevel/HighLevelUtils.hpp b/include/vast/Dialect/HighLevel/HighLevelUtils.hpp index 363f4cd95c..05d61616a2 100644 --- a/include/vast/Dialect/HighLevel/HighLevelUtils.hpp +++ b/include/vast/Dialect/HighLevel/HighLevelUtils.hpp @@ -158,8 +158,8 @@ namespace vast::hl { walk_result users(hl::VarDeclOp var, auto scope, auto &&yield) { VAST_CHECK(var.hasGlobalStorage(), "Only global variables are supported"); - return scope.walk([&](GlobalRefOp op) { - return op.getGlobal() == var.getSymbolName() ? yield(op) : walk_result::advance(); + return scope.walk([&](DeclRefOp op) { + return op.getName() == var.getSymbolName() ? yield(op) : walk_result::advance(); }); } diff --git a/include/vast/Dialect/HighLevel/HighLevelVar.td b/include/vast/Dialect/HighLevel/HighLevelVar.td index 1428a75a4d..e763ce6ec3 100644 --- a/include/vast/Dialect/HighLevel/HighLevelVar.td +++ b/include/vast/Dialect/HighLevel/HighLevelVar.td @@ -4,156 +4,17 @@ #define VAST_DIALECT_HIGHLEVEL_IR_HIGHLEVELVAR include "vast/Dialect/Core/CoreTraits.td" - -class HighLevel_StorageClassAttr< string name, int val > - : I64EnumAttrCase< name, val > -{} - -class HighLevel_StorageClassList< string name, string summary, list cases > - : I64EnumAttr< name, summary, cases > -{} - -def HighLevel_SC_None : HighLevel_StorageClassAttr< "sc_none", 0 >; -def HighLevel_SC_Auto : HighLevel_StorageClassAttr< "sc_auto", 1 >; -def HighLevel_SC_Static : HighLevel_StorageClassAttr< "sc_static", 2 >; -def HighLevel_SC_Extern : HighLevel_StorageClassAttr< "sc_extern", 3 >; -def HighLevel_SC_PrivateExtern : HighLevel_StorageClassAttr< "sc_private_extern", 4 >; -def HighLevel_SC_Register : HighLevel_StorageClassAttr< "sc_register", 5 >; - -let cppNamespace = "::vast::hl" in -def HighLevel_StorageClass : HighLevel_StorageClassList< "StorageClass", "storage class", [ - HighLevel_SC_None, - HighLevel_SC_Auto, - HighLevel_SC_Static, - HighLevel_SC_Extern, - HighLevel_SC_PrivateExtern, - HighLevel_SC_Register -] >; - -// thread storage class - -class HighLevel_TSCAttr< string name, int val > : I64EnumAttrCase< name, val > {} - -class HighLevel_TSCList< string name, string summary, list cases > - : I64EnumAttr< name, summary, cases > -{} - -def HighLevel_TSC_None : HighLevel_TSCAttr< "tsc_none", 0 >; -def HighLevel_TSC_GNU_Thread : HighLevel_TSCAttr< "tsc_gnu_thread", 1 >; -def HighLevel_TSC_CXX_Thread : HighLevel_TSCAttr< "tsc_cxx_thread", 2 >; -def HighLevel_TSC_C_Thread : HighLevel_TSCAttr< "tsc_c_thread", 3 >; - -let cppNamespace = "::vast::hl" in -def HighLevel_ThreadStorage : HighLevel_TSCList< "TSClass", "thread storage class", -[ - HighLevel_TSC_None, - HighLevel_TSC_GNU_Thread, - HighLevel_TSC_CXX_Thread, - HighLevel_TSC_C_Thread -] >; - -// Storage Duration - -class HighLevel_StorageDurationAttr< string name, int val > : I64EnumAttrCase< name, val > {} - -class HighLevel_StorageDurationList< string name, string summary, list cases > - : I64EnumAttr< name, summary, cases > -{} - -def HighLevel_SD_FullExpression : HighLevel_StorageDurationAttr< "sd_none", 0 >; -def HighLevel_SD_Automatic : HighLevel_StorageDurationAttr< "sd_automatic", 1 >; -def HighLevel_SD_Thread : HighLevel_StorageDurationAttr< "sd_thread", 2 >; -def HighLevel_SD_Static : HighLevel_StorageDurationAttr< "sd_static", 3 >; -def HighLevel_SD_Dynamic : HighLevel_StorageDurationAttr< "sd_dynamic", 4 >; - -let cppNamespace = "::vast::hl" in -def HighLevel_StorageDuration - : HighLevel_StorageDurationList< "StorageDuration", "storage duration", -[ - HighLevel_SD_FullExpression, - HighLevel_SD_Automatic, - HighLevel_SD_Thread, - HighLevel_SD_Static, - HighLevel_SD_Dynamic -] >; - -class HighLevel_StorageDurationImpl -{ - code storageDurationImpl = [{ - bool hasLocalStorage(); - - bool isLocalVarDecl(); - - bool isStaticLocal(); - - bool hasExternalStorage(); - - bool hasGlobalStorage(); - - StorageDuration getStorageDuration(); - }]; -} - -// declaration context kinds -class HighLevel_DeclContextAttr< string name, int val > : I64EnumAttrCase< name, val > {} - -class HighLevel_DeclContextList< string name, string summary, list cases > - : I64EnumAttr< name, summary, cases > -{} - -def HighLevel_DC_Function : HighLevel_DeclContextAttr< "dc_function", 0 >; -def HighLevel_DC_Method : HighLevel_DeclContextAttr< "dc_method", 1 >; -def HighLevel_DC_Block : HighLevel_DeclContextAttr< "dc_block", 2 >; -def HighLevel_DC_Capture : HighLevel_DeclContextAttr< "dc_capture", 3 >; -def HighLevel_DC_TranslationUnit : HighLevel_DeclContextAttr< "dc_translation_unit", 4 >; -def HighLevel_DC_Record : HighLevel_DeclContextAttr< "dc_record", 5 >; -def HighLevel_DC_Enum : HighLevel_DeclContextAttr< "dc_enum", 6 >; -def HighLevel_DC_Namespace : HighLevel_DeclContextAttr< "dc_namespace", 7 >; - -let cppNamespace = "::vast::hl" in -def HighLevel_DeclContextKind - : HighLevel_DeclContextList< "DeclContextKind", "declaration context kind", -[ - HighLevel_DC_Function, - HighLevel_DC_Method, - HighLevel_DC_Block, - HighLevel_DC_Capture, - HighLevel_DC_TranslationUnit, - HighLevel_DC_Record, - HighLevel_DC_Enum, - HighLevel_DC_Namespace -] >; - -class HighLevel_DeclContextImpl -{ - code declContextImpl = [{ - DeclContextKind getDeclContextKind(); - - bool isStaticDataMember(); - - bool isInFileContext(); - - bool isInFunctionOrMethodContext(); - - bool isInRecordContext(); - - bool isFileVarDecl(); - }]; -} - -class HighLevel_StorageSpecifiers : - HighLevel_StorageDurationImpl, - HighLevel_DeclContextImpl -{ - code storageSpecifiersImpl = - storageDurationImpl # - declContextImpl; -} +include "vast/Dialect/Core/StorageInfo.td" +include "vast/Dialect/Core/Interfaces/DeclStorageInterface.td" +include "vast/Dialect/Core/LinkageHelper.td" // Variable Operation def HighLevel_VarDeclOp - : HighLevel_Op< "var", [Core_VarSymbol] > - , HighLevel_StorageSpecifiers + : HighLevel_Op< "var", [ + Core_VarSymbol, + Core_DeclStorageInterface, + DeclareOpInterfaceMethods< Core_DeclStorageInterface > + ] > { let summary = "VAST variable declaration"; let description = [{ VAST variable declaration }]; @@ -161,8 +22,9 @@ def HighLevel_VarDeclOp let arguments = (ins SymbolNameAttr:$sym_name, TypeAttr:$type, - HighLevel_StorageClass:$storageClass, - HighLevel_ThreadStorage:$threadStorageClass + Core_StorageClass:$storageClass, + Core_ThreadStorage:$threadStorageClass, + OptionalAttr:$linkage ); let regions = (region @@ -170,26 +32,24 @@ def HighLevel_VarDeclOp AnyRegion:$allocation_size ); - let skipDefaultBuilders = 1; let builders = [ OpBuilder<(ins "Type":$type, "llvm::StringRef":$sym_name, - "StorageClass":$storageClass, - "TSClass":$threadStorageClass, + "core::StorageClass":$storageClass, + "core::TSClass":$threadStorageClass, + CArg< "std::optional< core::GlobalLinkageKind >", "std::nullopt">:$linkage, CArg< "maybe_builder_callback_ref", "std::nullopt" >:$initBuilder, CArg< "maybe_builder_callback_ref", "std::nullopt" >:$allocaBuilder )> ]; let assemblyFormat = [{ - $sym_name attr-dict custom< StorageClasses >($storageClass, $threadStorageClass) + $sym_name attr-dict (`,`$linkage^)? custom< StorageClasses >($storageClass, $threadStorageClass) `:` $type (`=` $initializer^)? (`allocation_size` $allocation_size^)? }]; - - let extraClassDeclaration = storageSpecifiersImpl; } #endif // VAST_DIALECT_HIGHLEVEL_IR_HIGHLEVELVAR diff --git a/include/vast/Dialect/LowLevel/LowLevelOps.hpp b/include/vast/Dialect/LowLevel/LowLevelOps.hpp index 8535ee16ee..9cbe3cf11c 100644 --- a/include/vast/Dialect/LowLevel/LowLevelOps.hpp +++ b/include/vast/Dialect/LowLevel/LowLevelOps.hpp @@ -24,6 +24,8 @@ VAST_RELAX_WARNINGS #include "vast/Dialect/Core/CoreTypes.hpp" #include "vast/Dialect/Core/CoreAttributes.hpp" +#include "vast/Dialect/HighLevel/HighLevelOps.hpp" +#include "vast/Dialect/Core/Interfaces/DeclStorageInterface.hpp" #include "vast/Util/Common.hpp" #define GET_OP_CLASSES diff --git a/include/vast/Dialect/LowLevel/LowLevelOps.td b/include/vast/Dialect/LowLevel/LowLevelOps.td index 522f2ef0db..584b8f3b85 100644 --- a/include/vast/Dialect/LowLevel/LowLevelOps.td +++ b/include/vast/Dialect/LowLevel/LowLevelOps.td @@ -12,6 +12,8 @@ include "vast/Dialect/Core/Interfaces/SymbolInterface.td" include "vast/Interfaces/ElementTypeInterface.td" include "vast/Dialect/Core/CoreTraits.td" +include "vast/Dialect/Core/StorageInfo.td" +include "vast/Dialect/Core/Interfaces/DeclStorageInterface.td" include "vast/Dialect/Core/Interfaces/SymbolInterface.td" include "vast/Dialect/Core/Interfaces/SymbolTableInterface.td" @@ -84,14 +86,23 @@ def LowLevel_Store } def LowLevel_Cell - : LowLevel_Op< "cell", [Core_VarSymbol] > - , Arguments<(ins SymbolNameAttr:$sym_name)> + : LowLevel_Op< "cell", [ + Core_VarSymbol, + Core_DeclStorageInterface, + DeclareOpInterfaceMethods< Core_DeclStorageInterface > + ] > + , Arguments<(ins + SymbolNameAttr:$sym_name, + Core_StorageClass:$storageClass, + Core_ThreadStorage:$threadStorageClass + )> , Results<(outs AnyType:$result)> { let summary = "Cell that holds the value and is accessible trhough SSA result."; let assemblyFormat = [{ - $sym_name attr-dict `:` type($result) + $sym_name attr-dict custom< StorageClasses >($storageClass, $threadStorageClass) + `:` type($result) }]; } diff --git a/lib/vast/CodeGen/DefaultDeclVisitor.cpp b/lib/vast/CodeGen/DefaultDeclVisitor.cpp index 0affa9ec3e..f02cf00177 100644 --- a/lib/vast/CodeGen/DefaultDeclVisitor.cpp +++ b/lib/vast/CodeGen/DefaultDeclVisitor.cpp @@ -139,34 +139,34 @@ namespace vast::cg { // Variable Declaration // - hl::StorageClass storage_class(const clang_var_decl *decl) { + core::StorageClass storage_class(const clang_var_decl *decl) { switch (decl->getStorageClass()) { case clang::SC_None: - return hl::StorageClass::sc_none; + return core::StorageClass::sc_none; case clang::SC_Auto: - return hl::StorageClass::sc_auto; + return core::StorageClass::sc_auto; case clang::SC_Static: - return hl::StorageClass::sc_static; + return core::StorageClass::sc_static; case clang::SC_Extern: - return hl::StorageClass::sc_extern; + return core::StorageClass::sc_extern; case clang::SC_PrivateExtern: - return hl::StorageClass::sc_private_extern; + return core::StorageClass::sc_private_extern; case clang::SC_Register: - return hl::StorageClass::sc_register; + return core::StorageClass::sc_register; } VAST_UNIMPLEMENTED_MSG("unknown storage class"); } - hl::TSClass thread_storage_class(const clang_var_decl *decl) { + core::TSClass thread_storage_class(const clang_var_decl *decl) { switch (decl->getTSCSpec()) { case clang::TSCS_unspecified: - return hl::TSClass::tsc_none; + return core::TSClass::tsc_none; case clang::TSCS___thread: - return hl::TSClass::tsc_gnu_thread; + return core::TSClass::tsc_gnu_thread; case clang::TSCS_thread_local: - return hl::TSClass::tsc_cxx_thread; + return core::TSClass::tsc_cxx_thread; case clang::TSCS__Thread_local: - return hl::TSClass::tsc_c_thread; + return core::TSClass::tsc_c_thread; } VAST_UNIMPLEMENTED_MSG("unknown thread storage class"); } @@ -216,6 +216,16 @@ namespace vast::cg { .freeze(); }; + auto linkage_builder = [](const clang::VarDecl *decl) { + auto gva_linkage = decl->getASTContext().GetGVALinkageForVariable(decl); + return core::get_declarator_linkage( + decl, + gva_linkage, + decl->getType().isConstQualified() + ); + }; + + auto var = maybe_declare([&] { return bld.compose< hl::VarDeclOp >() .bind(self.location(decl)) @@ -223,6 +233,7 @@ namespace vast::cg { .bind(self.symbol(decl)) .bind_always(storage_class(decl)) .bind_always(thread_storage_class(decl)) + .bind_choose(is_global, std::optional(linkage_builder(decl)), std::nullopt) // FIXME: The initializer region is filled later as it might // have references to the VarDecl we are currently // visiting - int *x = malloc(sizeof(*x)) diff --git a/lib/vast/CodeGen/DefaultStmtVisitor.cpp b/lib/vast/CodeGen/DefaultStmtVisitor.cpp index fce66f0fc3..a02cb3e6e8 100644 --- a/lib/vast/CodeGen/DefaultStmtVisitor.cpp +++ b/lib/vast/CodeGen/DefaultStmtVisitor.cpp @@ -628,12 +628,8 @@ namespace vast::cg auto underlying = expr->getDecl()->getUnderlyingDecl(); return llvm::TypeSwitch< const clang::NamedDecl *, operation >(underlying) .Case< clang::EnumConstantDecl >([&] (auto /* e */) { return visit_enum_decl_ref(expr); }) - .Case< clang::VarDecl >([&] (auto v) { - if (v->isFileVarDecl()) { - return visit_file_var_decl_ref(expr); - } else { - return visit_var_decl_ref(expr); - } + .Case< clang::VarDecl >([&] (auto v) { + return visit_var_decl_ref(expr); }) .Case< clang::FunctionDecl >([&] (auto) { return visit_function_decl_ref(expr); }) .Default([](const clang::NamedDecl *) { return operation{}; }); @@ -647,14 +643,6 @@ namespace vast::cg .freeze(); } - operation default_stmt_visitor::visit_file_var_decl_ref(const clang::DeclRefExpr *expr) { - return bld.compose< hl::GlobalRefOp >() - .bind(self.location(expr)) - .bind(visit_as_lvalue_type(self, mctx, expr->getType())) - .bind(self.symbol(expr)) - .freeze(); - } - operation default_stmt_visitor::visit_var_decl_ref(const clang::DeclRefExpr *expr) { if (auto name = self.symbol(expr)) { return bld.compose< hl::DeclRefOp >() diff --git a/lib/vast/Conversion/FromHL/Passes.cpp b/lib/vast/Conversion/FromHL/Passes.cpp index 00164b7f59..439b5c1b64 100644 --- a/lib/vast/Conversion/FromHL/Passes.cpp +++ b/lib/vast/Conversion/FromHL/Passes.cpp @@ -42,6 +42,10 @@ namespace vast::conv::pipeline { return pass(createVarsToCellsPass); } + pipeline_step_ptr evict_static_locals() { + return pass(createEvictStaticLocalsPass); + } + pipeline_step_ptr refs_to_ssa() { return pass(createRefsToSSAPass) .depends_on(vars_to_cells); @@ -56,6 +60,7 @@ namespace vast::conv::pipeline { return compose("to-mem", vars_to_cells, refs_to_ssa, + evict_static_locals, strip_param_lvalues ); } diff --git a/lib/vast/Conversion/Generic/LowerValueCategories.cpp b/lib/vast/Conversion/Generic/LowerValueCategories.cpp index a5a90ee469..4483be0052 100644 --- a/lib/vast/Conversion/Generic/LowerValueCategories.cpp +++ b/lib/vast/Conversion/Generic/LowerValueCategories.cpp @@ -463,7 +463,6 @@ namespace vast::conv { patterns.add< fallback >(tc, mctx); patterns.add< store_and_forward_ptr< ll::CellInit > >(mctx, tc); patterns.add< - ignore< hl::DeclRefOp >, ignore< hl::Deref >, ignore< hl::AddressOf > >(mctx, tc); diff --git a/lib/vast/Conversion/ToLLVM/IRsToLLVM.cpp b/lib/vast/Conversion/ToLLVM/IRsToLLVM.cpp index a24d6d942f..50533590a8 100644 --- a/lib/vast/Conversion/ToLLVM/IRsToLLVM.cpp +++ b/lib/vast/Conversion/ToLLVM/IRsToLLVM.cpp @@ -23,6 +23,7 @@ VAST_UNRELAX_WARNINGS #include "vast/Dialect/Core/CoreAttributes.hpp" #include "vast/Dialect/Core/CoreOps.hpp" +#include "vast/Dialect/Core/Linkage.hpp" #include "vast/Dialect/LowLevel/LowLevelOps.hpp" @@ -43,7 +44,6 @@ VAST_UNRELAX_WARNINGS namespace vast::conv::irstollvm { using ignore_patterns = util::type_list< - ignore_pattern< hl::DeclRefOp >, ignore_pattern< hl::PredefinedExpr >, ignore_pattern< hl::AddressOf >, ignore_pattern< hl::NullStmt >, @@ -356,28 +356,26 @@ namespace vast::conv::irstollvm auto t = mlir::dyn_cast< hl::PointerType >(op.getType()); auto target_type = this->convert(t.getElementType()); - // Sadly, we cannot build `mlir::LLVM::GlobalOp` without - // providing a value attribute. - auto create_dummy_value = [&] () -> mlir::Attribute { - if (auto trg_arr = mlir::dyn_cast< mlir::LLVM::LLVMArrayType >(target_type)) { - attrs_t arr(trg_arr.getNumElements(), - rewriter.getIntegerAttr(rewriter.getIndexType(), 0)); - return rewriter.getArrayAttr(arr); + // So we know this is a global, otherwise it would be in `ll:`. + auto linkage = op.getLinkage(); + if (!linkage) { + if (op.isStaticLocal()) { + linkage = core::GlobalLinkageKind::InternalLinkage; + } else { + VAST_REPORT("Global var without linkage information."); + return mlir::failure(); } - return rewriter.getIntegerAttr(rewriter.getIndexType(), 0); - }; + } - // So we know this is a global, otherwise it would be in `ll:`. auto gop = rewriter.create< mlir::LLVM::GlobalOp >( op.getLoc(), target_type, // TODO(conv:irstollvm): Constant. - true, - LLVM::Linkage::Internal, - op.getSymbolName(), create_dummy_value()); - - // If we want the global to have a body it cannot have value attribute. - gop.removeValueAttr(); + false, + core::convert_linkage_to_llvm(linkage.value()), + op.getSymbolName(), + mlir::Attribute() + ); // We could probably try to analyze the region to see if it isn't // a case where we can just do an attribute, but for now let's @@ -391,9 +389,9 @@ namespace vast::conv::irstollvm }; - struct global_ref : base_pattern< hl::GlobalRefOp > + struct global_ref : base_pattern< hl::DeclRefOp > { - using op_t = hl::GlobalRefOp; + using op_t = hl::DeclRefOp; using base = base_pattern< op_t >; using base::base; @@ -406,7 +404,7 @@ namespace vast::conv::irstollvm auto addr_of = rewriter.template create< mlir::LLVM::AddressOfOp >( op.getLoc(), target_type, - op.getGlobal()); + op.getName()); rewriter.replaceOp(op, addr_of); return logical_result::success(); } @@ -452,11 +450,13 @@ namespace vast::conv::irstollvm // want to lower them all. - // TODO(lukas): Linkage? - auto linkage = LLVM::Linkage::External; + auto linkage = func_op.getLinkage(); + VAST_CHECK(linkage, "Attempting lower function without set linkage {0}", func_op); auto new_func = rewriter.create< llvm_func_op >( - func_op.getLoc(), func_op.getName(), - target_type, linkage, + func_op.getLoc(), + func_op.getName(), + target_type, + core::convert_linkage_to_llvm(linkage.value()), func_op.isVarArg(), LLVM::CConv::C ); diff --git a/lib/vast/Conversion/ToMem/CMakeLists.txt b/lib/vast/Conversion/ToMem/CMakeLists.txt index 2e1ac897ed..0c444bbe63 100644 --- a/lib/vast/Conversion/ToMem/CMakeLists.txt +++ b/lib/vast/Conversion/ToMem/CMakeLists.txt @@ -1,6 +1,7 @@ # Copyright (c) 2024-present, Trail of Bits, Inc. add_vast_conversion_library(ToMemConversionPasses + EvictStaticLocals.cpp RefsToSSA.cpp StripParamLValues.cpp VarsToCells.cpp diff --git a/lib/vast/Conversion/ToMem/EvictStaticLocals.cpp b/lib/vast/Conversion/ToMem/EvictStaticLocals.cpp new file mode 100644 index 0000000000..84cefaf2d0 --- /dev/null +++ b/lib/vast/Conversion/ToMem/EvictStaticLocals.cpp @@ -0,0 +1,122 @@ +// Copyright (c) 2024-present, Trail of Bits, Inc. + +#include "vast/Util/Warnings.hpp" + +#include "vast/Conversion/Passes.hpp" + +VAST_RELAX_WARNINGS +#include +#include +#include +VAST_UNRELAX_WARNINGS + +#include "../PassesDetails.hpp" + +#include "vast/Util/Common.hpp" +#include "vast/Conversion/Common/Mixins.hpp" +#include "vast/Conversion/Common/Patterns.hpp" + +namespace vast::conv { + namespace pattern { + struct move_static_local : operation_conversion_pattern< hl::VarDeclOp > + { + using base = operation_conversion_pattern< hl::VarDeclOp >; + using base::base; + + using adaptor_t = hl::VarDeclOp::Adaptor; + + logical_result matchAndRewrite( + hl::VarDeclOp op, adaptor_t adaptor, conversion_rewriter &rewriter + ) const override { + auto parent_fn = op->getParentOfType< mlir::FunctionOpInterface >(); + if (!parent_fn) + return mlir::failure(); + + auto guard = insertion_guard(rewriter); + auto &module_block = parent_fn->getParentOfType< core::ModuleOp >().getBody().front(); + rewriter.setInsertionPoint(&module_block, module_block.begin()); + + auto new_decl = rewriter.create< hl::VarDeclOp >( + op.getLoc(), + op.getType(), + (parent_fn.getName() + "." + op.getSymName()).str(), + op.getStorageClass(), + op.getThreadStorageClass(), + std::optional(core::GlobalLinkageKind::InternalLinkage) + ); + + // Save current context informationinto the op to make sure the information stays valid + new_decl->setAttr("context", core::DeclContextKindAttr::get(op.getContext(), op.getDeclContextKind())); + + new_decl.getInitializer().takeBody(op.getInitializer()); + new_decl.getAllocationSize().takeBody(op.getAllocationSize()); + + rewriter.eraseOp(op); + + return mlir::success(); + } + + static void legalize(conversion_target &trg) { + trg.addDynamicallyLegalOp< hl::VarDeclOp >([] (hl::VarDeclOp op) { + return !(op.isStaticLocal() && op->getParentOfType< mlir::FunctionOpInterface >()); + }); + } + }; + + struct update_decl_ref : operation_conversion_pattern< hl::DeclRefOp > + { + using base = operation_conversion_pattern< hl::DeclRefOp >; + using base::base; + + using adaptor_t = hl::DeclRefOp::Adaptor; + + logical_result matchAndRewrite( + hl::DeclRefOp op, adaptor_t adaptor, conversion_rewriter &rewriter + ) const override { + auto var = core::symbol_table::lookup< core::var_symbol >(op, op.getName()); + if (auto decl_storage = mlir::dyn_cast< core::DeclStorageInterface>(var)) { + auto parent_fn = op->getParentOfType< mlir::FunctionOpInterface >(); + + if (!parent_fn || !decl_storage.isStaticLocal()) + return mlir::failure(); + + rewriter.replaceOpWithNewOp< hl::DeclRefOp >( + op, + op.getType(), + (parent_fn.getName() + "." + op.getName()).str() + ); + return mlir::success(); + } + return mlir::failure(); + } + + static void legalize(conversion_target &trg) { + trg.addDynamicallyLegalOp< hl::DeclRefOp >([&](hl::DeclRefOp op) { + auto var = core::symbol_table::lookup< core::var_symbol >(op, op.getName()); + if (auto decl_storage = mlir::dyn_cast< core::DeclStorageInterface>(var)) { + return !(decl_storage.isStaticLocal() && var->getParentOfType< mlir::FunctionOpInterface >()); + } + return (bool)var; + }); + } + }; + } + + struct EvictStaticLocalsPass : ConversionPassMixin< EvictStaticLocalsPass, EvictStaticLocalsBase > + { + using base = ConversionPassMixin< EvictStaticLocalsPass, EvictStaticLocalsBase >; + + static conversion_target create_conversion_target(mcontext_t &mctx) { + return conversion_target(mctx); + } + + static void populate_conversions(auto &cfg) { + base::populate_conversions< pattern::move_static_local >(cfg); + base::populate_conversions< pattern::update_decl_ref >(cfg); + } + }; +} // namespace vast::conv + +std::unique_ptr< mlir::Pass > vast::createEvictStaticLocalsPass() { + return std::make_unique< vast::conv::EvictStaticLocalsPass >(); +} diff --git a/lib/vast/Conversion/ToMem/RefsToSSA.cpp b/lib/vast/Conversion/ToMem/RefsToSSA.cpp index 800d99fc17..d86f6d30d9 100644 --- a/lib/vast/Conversion/ToMem/RefsToSSA.cpp +++ b/lib/vast/Conversion/ToMem/RefsToSSA.cpp @@ -41,6 +41,17 @@ namespace vast::conv { rewriter.replaceOp(op, var); return mlir::success(); } + + static void legalize(conversion_target &trg) { + trg.addDynamicallyLegalOp< hl::DeclRefOp >([] (hl::DeclRefOp op) { + auto var = core::symbol_table::lookup< core::var_symbol >(op, op.getName()); + // Declarations with global storage are not cells to keep their init region + if (auto decl_storage = mlir::dyn_cast< core::DeclStorageInterface >(var)) { + return decl_storage.hasGlobalStorage(); + } + return false; + }); + } }; } // namespace pattern diff --git a/lib/vast/Conversion/ToMem/VarsToCells.cpp b/lib/vast/Conversion/ToMem/VarsToCells.cpp index 7cd0633388..e9f72fc5d8 100644 --- a/lib/vast/Conversion/ToMem/VarsToCells.cpp +++ b/lib/vast/Conversion/ToMem/VarsToCells.cpp @@ -45,7 +45,7 @@ namespace vast::conv { logical_result matchAndRewrite( hl::VarDeclOp op, adaptor_t adaptor, conversion_rewriter &rewriter ) const override { - auto cell = rewriter.create< ll::Cell >(op.getLoc(), op.getType(), op.getSymName()); + auto cell = rewriter.create< ll::Cell >(op.getLoc(), op.getType(), op.getSymName(), op.getStorageClass(), op.getThreadStorageClass()); if (auto &init = op.getInitializer(); !init.empty()) { auto yield = inline_init_region(op, rewriter); @@ -82,7 +82,7 @@ namespace vast::conv { auto param = op.getParam(); auto type = param.getType(); auto loc = op.getLoc(); - auto cell = rewriter.create< ll::Cell >(loc, type, op.getSymName()); + auto cell = rewriter.create< ll::Cell >(loc, type, op.getSymName(), core::StorageClass::sc_none, core::TSClass::tsc_none); rewriter.create< ll::CellInit >(loc, type, cell, param); rewriter.eraseOp(op); return mlir::success(); diff --git a/lib/vast/Dialect/Core/CoreAttributes.cpp b/lib/vast/Dialect/Core/CoreAttributes.cpp index b32cf3354e..7c003d2dca 100644 --- a/lib/vast/Dialect/Core/CoreAttributes.cpp +++ b/lib/vast/Dialect/Core/CoreAttributes.cpp @@ -33,4 +33,48 @@ namespace vast::core return op->getAttrOfType< mlir::FlatSymbolRefAttr >("callee"); } + ParseResult parseStorageClasses( + Parser &parser, Attribute &storage_class, Attribute &thread_storage_class + ) { + std::string keyword; + auto parse_result = parser.parseOptionalKeywordOrString(&keyword); + + if (mlir::failed(parse_result)) { + storage_class = core::StorageClassAttr::get(parser.getContext(), core::StorageClass::sc_none); + thread_storage_class = core::TSClassAttr::get(parser.getContext(), core::TSClass::tsc_none); + return mlir::success(); + } else if (auto attr = symbolizeEnum< core::StorageClass >(keyword)) { + storage_class = core::StorageClassAttr::get(parser.getContext(), attr.value()); + } else if (auto attr = symbolizeEnum< core::TSClass >(keyword)) { + storage_class = core::StorageClassAttr::get(parser.getContext(), core::StorageClass::sc_none); + thread_storage_class = core::TSClassAttr::get(parser.getContext(), attr.value()); + return mlir::success(); + } else { + return mlir::failure(); + } + + parse_result = parser.parseOptionalKeywordOrString(&keyword); + if (mlir::failed(parse_result)) { + thread_storage_class = core::TSClassAttr::get(parser.getContext(), core::TSClass::tsc_none); + } else if (auto attr = symbolizeEnum< core::TSClass >(keyword)) { + thread_storage_class = core::TSClassAttr::get(parser.getContext(), attr.value()); + } else { + return mlir::failure(); + } + + return mlir::success(); + } + + void printStorageClasses( + Printer &printer, mlir::Operation *op, core::StorageClassAttr storage_class, core::TSClassAttr thread_storage_class + ) { + if (storage_class.getValue() != core::StorageClass::sc_none) { + printer << ' ' << storage_class.getValue(); + } + + if (thread_storage_class.getValue() != core::TSClass::tsc_none) { + printer << ' ' << thread_storage_class.getValue(); + } + } + } // namespace vast::core diff --git a/lib/vast/Dialect/Core/Interfaces/CMakeLists.txt b/lib/vast/Dialect/Core/Interfaces/CMakeLists.txt index d14d714022..6f91fa4033 100644 --- a/lib/vast/Dialect/Core/Interfaces/CMakeLists.txt +++ b/lib/vast/Dialect/Core/Interfaces/CMakeLists.txt @@ -1,10 +1,14 @@ set(VAST_OPTIONAL_SOURCES + DeclStorageInterface.cpp SymbolInterface.cpp SymbolTableInterface.cpp SymbolRefInterface.cpp TypeDefinitionInterface.cpp ) +add_vast_interface_library(DeclStorageInterface + DeclStorageInterface.cpp +) add_vast_interface_library(SymbolInterface SymbolInterface.cpp diff --git a/lib/vast/Dialect/Core/Interfaces/DeclStorageInterface.cpp b/lib/vast/Dialect/Core/Interfaces/DeclStorageInterface.cpp new file mode 100644 index 0000000000..67b0f91dc1 --- /dev/null +++ b/lib/vast/Dialect/Core/Interfaces/DeclStorageInterface.cpp @@ -0,0 +1,10 @@ +// Copyright (c) 2024-present, Trail of Bits, Inc. + +#include "vast/Dialect/Core/Interfaces/DeclStorageInterface.hpp" + +//===----------------------------------------------------------------------===// +// Decl Storage Interfaces +//===----------------------------------------------------------------------===// + +/// Include the generated symbol interfaces. +#include "vast/Dialect/Core/Interfaces/DeclStorageInterface.cpp.inc" diff --git a/lib/vast/Dialect/Core/Linkage.cpp b/lib/vast/Dialect/Core/Linkage.cpp index d6629fae16..217ef5cad3 100644 --- a/lib/vast/Dialect/Core/Linkage.cpp +++ b/lib/vast/Dialect/Core/Linkage.cpp @@ -170,6 +170,13 @@ namespace vast::core { return GlobalLinkageKind::ExternalWeakLinkage; } } + if (const auto *var = llvm::dyn_cast< clang::VarDecl >(decl)) { + if (!var->hasDefinition() && var->isExternallyVisible() + && (var->hasAttr< clang::WeakAttr >() || var->isWeakImported())) + { + return core::GlobalLinkageKind::ExternalWeakLinkage; + } + } if (decl->hasAttr< clang::WeakAttr >()) { if (is_constant) @@ -276,4 +283,31 @@ namespace vast::core { return get_declarator_linkage(decl, linkage, /* is const variable */ false); } + mlir::LLVM::Linkage convert_linkage_to_llvm(core::GlobalLinkageKind linkage) { + switch (linkage) { + case core::GlobalLinkageKind::ExternalLinkage: + return mlir::LLVM::Linkage::External; + case core::GlobalLinkageKind::AvailableExternallyLinkage: + return mlir::LLVM::Linkage::AvailableExternally; + case core::GlobalLinkageKind::LinkOnceAnyLinkage: + return mlir::LLVM::Linkage::Linkonce; + case core::GlobalLinkageKind::LinkOnceODRLinkage: + return mlir::LLVM::Linkage::LinkonceODR; + case core::GlobalLinkageKind::WeakAnyLinkage: + return mlir::LLVM::Linkage::Weak; + case core::GlobalLinkageKind::WeakODRLinkage: + return mlir::LLVM::Linkage::WeakODR; + case core::GlobalLinkageKind::InternalLinkage: + return mlir::LLVM::Linkage::Internal; + case core::GlobalLinkageKind::PrivateLinkage: + return mlir::LLVM::Linkage::Private; + case core::GlobalLinkageKind::ExternalWeakLinkage: + return mlir::LLVM::Linkage::ExternWeak; + case core::GlobalLinkageKind::CommonLinkage: + return mlir::LLVM::Linkage::Common; + case core::GlobalLinkageKind::AppendingLinkage: + return mlir::LLVM::Linkage::Appending; + } + } + } // namespace vast::core diff --git a/lib/vast/Dialect/HighLevel/HighLevelOps.cpp b/lib/vast/Dialect/HighLevel/HighLevelOps.cpp index 139c0c2f6f..e2dca19916 100644 --- a/lib/vast/Dialect/HighLevel/HighLevelOps.cpp +++ b/lib/vast/Dialect/HighLevel/HighLevelOps.cpp @@ -342,66 +342,26 @@ namespace vast::hl Builder &bld, State &st, Type type, llvm::StringRef name, - StorageClass storage_class, - TSClass thread_storage_class, + core::StorageClass storage_class, + core::TSClass thread_storage_class, + std::optional< core::GlobalLinkageKind > linkage, maybe_builder_callback_ref init, maybe_builder_callback_ref alloc ) { auto ctx = bld.getContext(); st.addAttribute(core::symbol_attr_name(), bld.getStringAttr(name)); st.addAttribute("type", mlir::TypeAttr::get(type)); - st.addAttribute("storageClass", StorageClassAttr::get(ctx, storage_class)); - st.addAttribute("threadStorageClass", TSClassAttr::get(ctx, thread_storage_class)); + st.addAttribute("storageClass", core::StorageClassAttr::get(ctx, storage_class)); + st.addAttribute("threadStorageClass", core::TSClassAttr::get(ctx, thread_storage_class)); + if (linkage) { + st.addAttribute("linkage", core::GlobalLinkageKindAttr::get(ctx, linkage.value())); + } InsertionGuard guard(bld); build_region(bld, st, init); build_region(bld, st, alloc); } - ParseResult parseStorageClasses( - Parser &parser, Attribute &storage_class, Attribute &thread_storage_class - ) { - std::string keyword; - auto parse_result = parser.parseOptionalKeywordOrString(&keyword); - - if (mlir::failed(parse_result)) { - storage_class = StorageClassAttr::get(parser.getContext(), StorageClass::sc_none); - thread_storage_class = TSClassAttr::get(parser.getContext(), TSClass::tsc_none); - return mlir::success(); - } else if (auto attr = symbolizeEnum< StorageClass >(keyword)) { - storage_class = StorageClassAttr::get(parser.getContext(), attr.value()); - } else if (auto attr = symbolizeEnum< TSClass >(keyword)) { - storage_class = StorageClassAttr::get(parser.getContext(), StorageClass::sc_none); - thread_storage_class = TSClassAttr::get(parser.getContext(), attr.value()); - return mlir::success(); - } else { - return mlir::failure(); - } - - parse_result = parser.parseOptionalKeywordOrString(&keyword); - if (mlir::failed(parse_result)) { - thread_storage_class = TSClassAttr::get(parser.getContext(), TSClass::tsc_none); - } else if (auto attr = symbolizeEnum< TSClass >(keyword)) { - thread_storage_class = TSClassAttr::get(parser.getContext(), attr.value()); - } else { - return mlir::failure(); - } - - return mlir::success(); - } - - void printStorageClasses( - Printer &printer, mlir::Operation *op, StorageClassAttr storage_class, TSClassAttr thread_storage_class - ) { - if (storage_class.getValue() != StorageClass::sc_none) { - printer << ' ' << storage_class.getValue(); - } - - if (thread_storage_class.getValue() != TSClass::tsc_none) { - printer << ' ' << thread_storage_class.getValue(); - } - } - void EnumDeclOp::build( Builder &bld, State &st, llvm::StringRef name, Type type, builder_callback_ref constants @@ -929,6 +889,8 @@ namespace vast::hl //===----------------------------------------------------------------------===// using namespace vast::hl; +using vast::core::parseStorageClasses; +using vast::core::printStorageClasses; #define GET_OP_CLASSES #include "vast/Dialect/HighLevel/HighLevel.cpp.inc" diff --git a/lib/vast/Dialect/HighLevel/HighLevelVar.cpp b/lib/vast/Dialect/HighLevel/HighLevelVar.cpp index 7c5af38276..41f3275abf 100644 --- a/lib/vast/Dialect/HighLevel/HighLevelVar.cpp +++ b/lib/vast/Dialect/HighLevel/HighLevelVar.cpp @@ -9,89 +9,4 @@ namespace vast::hl { - bool isFileContext(DeclContextKind kind) { - return kind == DeclContextKind::dc_translation_unit - || kind == DeclContextKind::dc_namespace; - } - - bool VarDeclOp::isInFileContext() { return isFileContext(getDeclContextKind()); } - - bool isFunctionOrMethodContext(DeclContextKind kind) { - return kind == DeclContextKind::dc_function - || kind == DeclContextKind::dc_method - || kind == DeclContextKind::dc_capture; - } - - bool VarDeclOp::isInFunctionOrMethodContext() { - return isFunctionOrMethodContext(getDeclContextKind()); - } - - bool isRecordContext(DeclContextKind kind) { return kind == DeclContextKind::dc_record; } - - bool VarDeclOp::isInRecordContext() { return isRecordContext(getDeclContextKind()); } - - DeclContextKind VarDeclOp::getDeclContextKind() { - auto st = core::get_effective_symbol_table_for< core::var_symbol >(*this)->get_defining_operation(); - if (mlir::isa< mlir::FunctionOpInterface >(st)) - return DeclContextKind::dc_function; - if (st->hasTrait< core::ScopeLikeTrait >()) - return DeclContextKind::dc_function; - if (mlir::isa< core::ModuleOp >(st)) - return DeclContextKind::dc_translation_unit; - if (mlir::isa< StructDeclOp >(st)) - return DeclContextKind::dc_record; - if (mlir::isa< EnumDeclOp >(st)) - return DeclContextKind::dc_enum; - VAST_UNIMPLEMENTED_MSG("unknown declaration context"); - } - - bool VarDeclOp::isStaticDataMember() { - // If it wasn't static, it would be a FieldDecl. - return isInRecordContext(); - } - - bool VarDeclOp::isFileVarDecl() { - return isInFileContext() || isStaticDataMember(); - } - - bool VarDeclOp::isLocalVarDecl() { return isInFunctionOrMethodContext(); } - - bool VarDeclOp::hasLocalStorage() { - switch (getStorageClass()) { - case StorageClass::sc_none: - return !isFileVarDecl() && getThreadStorageClass() == TSClass::tsc_none; - case StorageClass::sc_register: return isLocalVarDecl(); - case StorageClass::sc_auto: return true; - case StorageClass::sc_extern: - case StorageClass::sc_static: - case StorageClass::sc_private_extern: return false; - } - - VAST_UNIMPLEMENTED_MSG("unknown starage class"); - } - - bool VarDeclOp::isStaticLocal() { - if (isFileVarDecl()) - return false; - auto sc = getStorageClass(); - if (sc == StorageClass::sc_static) - return true; - auto tsc = getThreadStorageClass(); - return sc == StorageClass::sc_none && tsc == TSClass::tsc_cxx_thread; - } - - bool VarDeclOp::hasExternalStorage() { - auto sc = getStorageClass(); - return sc == StorageClass::sc_extern || sc == StorageClass::sc_private_extern; - } - - bool VarDeclOp::hasGlobalStorage() { return !hasLocalStorage(); } - - StorageDuration VarDeclOp::getStorageDuration() { - if (hasLocalStorage()) - return StorageDuration::sd_automatic; - if (getThreadStorageClass() != TSClass::tsc_none) - return StorageDuration::sd_thread; - return StorageDuration::sd_static; - } } // namespace vast::hl diff --git a/lib/vast/Dialect/LowLevel/LowLevelOps.cpp b/lib/vast/Dialect/LowLevel/LowLevelOps.cpp index 96a594148f..74304a1cb0 100644 --- a/lib/vast/Dialect/LowLevel/LowLevelOps.cpp +++ b/lib/vast/Dialect/LowLevel/LowLevelOps.cpp @@ -50,5 +50,8 @@ namespace vast::ll } // namespace vast::ll +using vast::core::parseStorageClasses; +using vast::core::printStorageClasses; + #define GET_OP_CLASSES #include "vast/Dialect/LowLevel/LowLevel.cpp.inc" diff --git a/test/lit.cfg.py b/test/lit.cfg.py index 5af157aba3..0ccd1b74eb 100644 --- a/test/lit.cfg.py +++ b/test/lit.cfg.py @@ -82,6 +82,7 @@ , "vast-hl-to-ll-geps" , "vast-vars-to-cells" , "vast-refs-to-ssa" + , "vast-evict-static-locals" , "vast-strip-param-lvalues" , "vast-lower-value-categories" , "vast-hl-to-lazy-regions" diff --git a/test/vast/Conversion/cmake-platform-test.c b/test/vast/Conversion/cmake-platform-test.c index 725f2c8a74..b6f842f261 100644 --- a/test/vast/Conversion/cmake-platform-test.c +++ b/test/vast/Conversion/cmake-platform-test.c @@ -24,7 +24,7 @@ #define SIZE (sizeof(unsigned short)) -// CHECK: constant @info_size() {{.*}} !llvm.array +// CHECK: @info_size() {{.*}} !llvm.array static char info_size[] = {'I', 'N', 'F', 'O', ':', 's','i','z','e','[', ('0' + ((SIZE / 10000)%10)), ('0' + ((SIZE / 1000)%10)), diff --git a/test/vast/Conversion/static-var-a.c b/test/vast/Conversion/static-var-a.c new file mode 100644 index 0000000000..8adf7d98b0 --- /dev/null +++ b/test/vast/Conversion/static-var-a.c @@ -0,0 +1,18 @@ +// RUN: %vast-front -vast-emit-mlir=hl -o - %s | %file-check %s -check-prefix=HL +// RUN: %check-evict-static-locals %s | %file-check %s -check-prefix=EVICTED +// RUN: %check-core-to-llvm %s | %file-check %s -check-prefix=LLVM + +// HL: hl.var @x sc_static +// HL: hl.ref @x + +// EVICTED: hl.var @foo.x {context = 0 : i64}, sc_static +// EVICTED: ll.func @foo +// EVICTED: hl.ref @foo.x + +// LLVM: llvm.mlir.global internal @foo.x() +// LLVM: llvm.func @foo +// LLVM: llvm.mlir.addressof @foo.x +int foo() { + static int x = 5; + return x++; +} diff --git a/test/vast/Conversion/subscript-b.c b/test/vast/Conversion/subscript-b.c index 2d7a6cc08a..afe4f97fc4 100644 --- a/test/vast/Conversion/subscript-b.c +++ b/test/vast/Conversion/subscript-b.c @@ -2,25 +2,25 @@ // RUN: %check-lower-value-categories %s | %file-check %s -check-prefix=VAL_CAT // RUN: %check-core-to-llvm %s | %file-check %s -check-prefix=C_LLVM -// STD_TYPES: hl.var @arr1 : !hl.lvalue> = { +// STD_TYPES: hl.var @arr1, : !hl.lvalue> = { -// VAL_CAT: hl.var @arr1 : !hl.ptr> = { +// VAL_CAT: hl.var @arr1, : !hl.ptr> = { // VAL_CAT: hl.value.yield {{.*}} : !hl.array<3, si32> -// C_LLVM: llvm.mlir.global internal constant @arr1() {addr_space = 0 : i32} : !llvm.array<3 x i32> { +// C_LLVM: llvm.mlir.global external @arr1() {addr_space = 0 : i32} : !llvm.array<3 x i32> { int arr1[] = { 0, 2, 4 }; -// STD_TYPES: [[V2:%[0-9]+]] = hl.globref @arr1 : !hl.lvalue> +// STD_TYPES: [[V2:%[0-9]+]] = hl.ref @arr1 : !hl.lvalue> // STD_TYPES: [[V3:%[0-9]+]] = hl.implicit_cast [[V2]] ArrayToPointerDecay : !hl.lvalue> -> !hl.ptr // STD_TYPES: [[V4:%[0-9]+]] = hl.const #core.integer<0> : si32 // STD_TYPES: [[V5:%[0-9]+]] = hl.subscript [[V3]] at [[[V4]] : si32] : !hl.ptr -> !hl.lvalue // STD_TYPES: [[V6:%[0-9]+]] = hl.implicit_cast [[V5]] LValueToRValue : !hl.lvalue -> si32 -// VAL_CAT: [[V1:%[0-9]+]] = hl.globref @arr1 : !hl.ptr> +// VAL_CAT: [[V1:%[0-9]+]] = hl.ref @arr1 : !hl.ptr> // VAL_CAT: [[V2:%[0-9]+]] = hl.implicit_cast [[V1]] ArrayToPointerDecay : !hl.ptr> -> !hl.ptr // VAL_CAT: [[V3:%[0-9]+]] = hl.const #core.integer<0> : si32 // VAL_CAT: [[V4:%[0-9]+]] = ll.subscript [[V2]] at [[[V3]] : si32] : !hl.ptr -> !hl.ptr diff --git a/test/vast/Dialect/HighLevel/array-a.c b/test/vast/Dialect/HighLevel/array-a.c index 9d2e8ff4ec..8fcbda626f 100644 --- a/test/vast/Dialect/HighLevel/array-a.c +++ b/test/vast/Dialect/HighLevel/array-a.c @@ -1,26 +1,26 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - -// CHECK: hl.var @ai : !hl.lvalue> +// CHECK: hl.var @ai, : !hl.lvalue> int ai[10]; -// CHECK: hl.var @aci : !hl.lvalue>> +// CHECK: hl.var @aci, : !hl.lvalue>> const int aci[5]; -// CHECK: hl.var @avi : !hl.lvalue>> +// CHECK: hl.var @avi, : !hl.lvalue>> volatile int avi[5]; -// CHECK: hl.var @acvi : !hl.lvalue>> +// CHECK: hl.var @acvi, : !hl.lvalue>> const volatile int acvi[5]; -// CHECK: hl.var @acvui : !hl.lvalue>> +// CHECK: hl.var @acvui, : !hl.lvalue>> const volatile unsigned int acvui[5]; -// CHECK: hl.var @af : !hl.lvalue> +// CHECK: hl.var @af, : !hl.lvalue> float af[10]; -// CHECK: hl.var @a3d : !hl.lvalue>>> +// CHECK: hl.var @a3d, : !hl.lvalue>>> float a3d[2][4][3]; -// CHECK: hl.var @ae : !hl.lvalue> +// CHECK: hl.var @ae, : !hl.lvalue> int ae[4 + 4*100]; diff --git a/test/vast/Dialect/HighLevel/array-b.c b/test/vast/Dialect/HighLevel/array-b.c index a300065146..df906864f1 100644 --- a/test/vast/Dialect/HighLevel/array-b.c +++ b/test/vast/Dialect/HighLevel/array-b.c @@ -1,5 +1,5 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - -// CHECK: hl.var @earr sc_extern : !hl.lvalue> +// CHECK: hl.var @earr, sc_extern : !hl.lvalue> extern int earr[]; diff --git a/test/vast/Dialect/HighLevel/array-c.c b/test/vast/Dialect/HighLevel/array-c.c index c15f2c30cc..007fcd5de8 100644 --- a/test/vast/Dialect/HighLevel/array-c.c +++ b/test/vast/Dialect/HighLevel/array-c.c @@ -1,7 +1,7 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - -// CHECK: hl.var @cai : !hl.lvalue>> = { +// CHECK: hl.var @cai, : !hl.lvalue>> = { // CHECK: [[V1:%[0-9]+]] = hl.const #core.integer<1> : !hl.int // CHECK: [[V2:%[0-9]+]] = hl.const #core.integer<2> : !hl.int // CHECK: [[V3:%[0-9]+]] = hl.const #core.integer<3> : !hl.int diff --git a/test/vast/Dialect/HighLevel/assign-a.c b/test/vast/Dialect/HighLevel/assign-a.c index 6035c2cda6..2e4ecea2c2 100644 --- a/test/vast/Dialect/HighLevel/assign-a.c +++ b/test/vast/Dialect/HighLevel/assign-a.c @@ -4,8 +4,8 @@ int a, b; void foo() { - // CHECK: [[A:%[0-9]+]] = hl.globref @a : !hl.lvalue - // CHECK: [[B:%[0-9]+]] = hl.globref @b : !hl.lvalue + // CHECK: [[A:%[0-9]+]] = hl.ref @a : !hl.lvalue + // CHECK: [[B:%[0-9]+]] = hl.ref @b : !hl.lvalue // CHECK: [[B2:%[0-9]+]] = hl.pre.inc [[B]] : !hl.lvalue -> !hl.int // CHECK: hl.assign [[B2]] to [[A]] : !hl.int, !hl.lvalue -> !hl.int a = ++b; diff --git a/test/vast/Dialect/HighLevel/assign-b.c b/test/vast/Dialect/HighLevel/assign-b.c index d1c15354c4..ccce6d2013 100644 --- a/test/vast/Dialect/HighLevel/assign-b.c +++ b/test/vast/Dialect/HighLevel/assign-b.c @@ -4,7 +4,7 @@ short a; void foo() { - // CHECK: [[A:%[0-9]+]] = hl.globref @a : !hl.lvalue + // CHECK: [[A:%[0-9]+]] = hl.ref @a : !hl.lvalue // CHECK: [[C:%[0-9]+]] = hl.const #core.integer<4> : !hl.int // CHECK: hl.assign.add [[C]] to [[A]] : !hl.int, !hl.lvalue -> !hl.short a += 4; diff --git a/test/vast/Dialect/HighLevel/cast-b.c b/test/vast/Dialect/HighLevel/cast-b.c index a24cc6e8db..e413cae7d2 100644 --- a/test/vast/Dialect/HighLevel/cast-b.c +++ b/test/vast/Dialect/HighLevel/cast-b.c @@ -4,7 +4,7 @@ // CHECK: hl.typedef @function_type : !core.fn<(!hl.lvalue, !hl.lvalue) -> (!hl.int)> typedef int function_type(int a, int b); -// CHECK: hl.var @p : !hl.lvalue>>>> +// CHECK: hl.var @p, : !hl.lvalue>>>> function_type *p[2]; int test_func(void) { diff --git a/test/vast/Dialect/HighLevel/constants-a.c b/test/vast/Dialect/HighLevel/constants-a.c index 8be57d4f08..74fe28b43f 100644 --- a/test/vast/Dialect/HighLevel/constants-a.c +++ b/test/vast/Dialect/HighLevel/constants-a.c @@ -1,31 +1,31 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - -// CHECK: hl.var @i : !hl.lvalue +// CHECK: hl.var @i, : !hl.lvalue // CHECK: hl.const #core.integer<0> : !hl.int int i = 0; -// CHECK: hl.var @ui : !hl.lvalue> +// CHECK: hl.var @ui, : !hl.lvalue> // CHECK: hl.const #core.integer<0> : !hl.int< unsigned > unsigned int ui = 0u; -// CHECK: hl.var @lli : !hl.lvalue +// CHECK: hl.var @lli, : !hl.lvalue // CHECK: hl.const #core.integer<0> : !hl.longlong long long int lli = 0ll; -// CHECK: hl.var @f : !hl.lvalue +// CHECK: hl.var @f, : !hl.lvalue // CHECK: hl.const #core.float<0.000000e+00> : !hl.float float f = 0.f; -// CHECK: hl.var @d : !hl.lvalue +// CHECK: hl.var @d, : !hl.lvalue // CHECK: hl.const #core.float<0.000000e+00> : !hl.double double d = 0.0; -// CHECK: hl.var @str : !hl.lvalue>> +// CHECK: hl.var @str, : !hl.lvalue>> // CHECK: hl.const "hello" : !hl.lvalue> const char *str = "hello"; -// CHECK: hl.var @arr : !hl.lvalue>> +// CHECK: hl.var @arr, : !hl.lvalue>> // CHECK: hl.const #core.integer<1> : !hl.int // CHECK: hl.const #core.integer<2> : !hl.int // CHECK: hl.const #core.integer<3> : !hl.int diff --git a/test/vast/Dialect/HighLevel/enum-a.c b/test/vast/Dialect/HighLevel/enum-a.c index fd23e41ca9..774f28f0d0 100644 --- a/test/vast/Dialect/HighLevel/enum-a.c +++ b/test/vast/Dialect/HighLevel/enum-a.c @@ -8,7 +8,7 @@ // CHECK: } enum color { RED, GREEN, BLUE }; -// CHECK: hl.var @c : !hl.lvalue>> +// CHECK: hl.var @c, : !hl.lvalue>> // CHECK: [[V1:%[0-9]+]] = hl.enumref @GREEN : !hl.int // CHECK: [[V2:%[0-9]+]] = hl.implicit_cast [[V1]] IntegralCast : !hl.int -> !hl.elaborated> // CHECK: hl.value.yield [[V2]] : !hl.elaborated> @@ -17,5 +17,5 @@ enum color c = GREEN; // CHECK: hl.typedef @color : !hl.elaborated> typedef enum color color; -// CHECK: hl.var @tc : !hl.lvalue>> +// CHECK: hl.var @tc, : !hl.lvalue>> color tc; diff --git a/test/vast/Dialect/HighLevel/enum-d.c b/test/vast/Dialect/HighLevel/enum-d.c index 8c705092ec..40508024f0 100644 --- a/test/vast/Dialect/HighLevel/enum-d.c +++ b/test/vast/Dialect/HighLevel/enum-d.c @@ -3,12 +3,12 @@ // CHECK: hl.enum @color : !hl.int< unsigned > enum color { RED, GREEN, BLUE }; -// CHECK: hl.var @r : !hl.lvalue>> +// CHECK: hl.var @r, : !hl.lvalue>> // CHECK: hl.enumref @RED : !hl.int enum color r = RED; // CHECK: hl.typedef @color_t : !hl.elaborated> -// CHECK: hl.var @x : !hl.lvalue>> +// CHECK: hl.var @x, : !hl.lvalue>> // CHECK: hl.enumref @GREEN : !hl.int typedef enum color color_t; color_t x = GREEN; diff --git a/test/vast/Dialect/HighLevel/enum-e.c b/test/vast/Dialect/HighLevel/enum-e.c index b72b87aa2e..6c34c8e9dc 100644 --- a/test/vast/Dialect/HighLevel/enum-e.c +++ b/test/vast/Dialect/HighLevel/enum-e.c @@ -13,7 +13,7 @@ struct Element { int z; enum State { SOLID, LIQUID, GAS, PLASMA } state; -// CHECK: hl.var @oxygen : !hl.lvalue>> +// CHECK: hl.var @oxygen, : !hl.lvalue>> // CHECK: [[V1:%[0-9]+]] = hl.const #core.integer<8> : !hl.int // CHECK: [[V2:%[0-9]+]] = hl.enumref @GAS : !hl.int // CHECK: [[V3:%[0-9]+]] = hl.implicit_cast [[V2]] IntegralCast : !hl.int -> !hl.elaborated> diff --git a/test/vast/Dialect/HighLevel/floats-a.c b/test/vast/Dialect/HighLevel/floats-a.c index 7de4014886..c9076b07c9 100644 --- a/test/vast/Dialect/HighLevel/floats-a.c +++ b/test/vast/Dialect/HighLevel/floats-a.c @@ -1,17 +1,17 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - -// CHECK: hl.var @fp16 : !hl.lvalue +// CHECK: hl.var @fp16, : !hl.lvalue __fp16 fp16 = 0.5; -// CHECK: hl.var @f : !hl.lvalue +// CHECK: hl.var @f, : !hl.lvalue // CHECK: hl.const #core.float<5.000000e-01> : !hl.float float f = 0.5f; -// CHECK: hl.var @d : !hl.lvalue +// CHECK: hl.var @d, : !hl.lvalue // CHECK: hl.const #core.float<5.000000e-01> : !hl.double double d = 0.5; -// CHECK: hl.var @ld : !hl.lvalue +// CHECK: hl.var @ld, : !hl.lvalue // CHECK: hl.const #core.float<5.000000e-01> : !hl.longdouble long double ld = 0.5L; diff --git a/test/vast/Dialect/HighLevel/glob-a.c b/test/vast/Dialect/HighLevel/glob-a.c index 5df553167b..4f95267777 100644 --- a/test/vast/Dialect/HighLevel/glob-a.c +++ b/test/vast/Dialect/HighLevel/glob-a.c @@ -1,12 +1,12 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - -// CHECK: hl.var @a : !hl.lvalue +// CHECK: hl.var @a, : !hl.lvalue int a = 0; // CHECK-LABEL: hl.func @main int main() { - // CHECK: [[G:%[0-9]+]] = hl.globref @a : !hl.lvalue + // CHECK: [[G:%[0-9]+]] = hl.ref @a : !hl.lvalue // CHECK: [[C:%[0-9]+]] = hl.const #core.integer<1> : !hl.int // CHECK: hl.assign [[C]] to [[G]] a = 1; diff --git a/test/vast/Dialect/HighLevel/glob-front-a.c b/test/vast/Dialect/HighLevel/glob-front-a.c index fd6796393e..21b87f3917 100644 --- a/test/vast/Dialect/HighLevel/glob-front-a.c +++ b/test/vast/Dialect/HighLevel/glob-front-a.c @@ -3,6 +3,6 @@ // CHECK: hl.var @NUM // CHECK: hl.value.yield short NUM = 10; -//CHECK: hl.globref @NUM +//CHECK: hl.ref @NUM //CHECK: hl.assign int main() {NUM = 11;} diff --git a/test/vast/Dialect/HighLevel/glob-front-b.c b/test/vast/Dialect/HighLevel/glob-front-b.c index 987098d0fa..f128d72a54 100644 --- a/test/vast/Dialect/HighLevel/glob-front-b.c +++ b/test/vast/Dialect/HighLevel/glob-front-b.c @@ -2,6 +2,6 @@ // CHECK: hl.var @NUM short NUM; -//CHECK: hl.globref @NUM +//CHECK: hl.ref @NUM //CHECK: hl.assign int main() {NUM = 10;} diff --git a/test/vast/Dialect/HighLevel/glob-front-c.c b/test/vast/Dialect/HighLevel/glob-front-c.c index 027f9dbe24..5103fce036 100644 --- a/test/vast/Dialect/HighLevel/glob-front-c.c +++ b/test/vast/Dialect/HighLevel/glob-front-c.c @@ -3,6 +3,6 @@ extern short GIB_SHORT(void); // CHECK: hl.var @NUM short NUM; -//CHECK: hl.globref @NUM +//CHECK: hl.ref @NUM //CHECK: hl.assign int main() {NUM = GIB_SHORT();} diff --git a/test/vast/Dialect/HighLevel/glob-front-d.c b/test/vast/Dialect/HighLevel/glob-front-d.c index 4ac41aaacb..649c7564b2 100644 --- a/test/vast/Dialect/HighLevel/glob-front-d.c +++ b/test/vast/Dialect/HighLevel/glob-front-d.c @@ -1,6 +1,6 @@ // RUN: %vast-front %s -vast-emit-mlir=hl -o - | %file-check %s -// CHECK: hl.var @a sc_static +// CHECK: hl.var @a, sc_static static int a = 2; int main() { diff --git a/test/vast/Dialect/HighLevel/glob-linkage-a.c b/test/vast/Dialect/HighLevel/glob-linkage-a.c new file mode 100644 index 0000000000..ff9af9b906 --- /dev/null +++ b/test/vast/Dialect/HighLevel/glob-linkage-a.c @@ -0,0 +1,16 @@ +// RUN: %vast-front %s -vast-emit-mlir=hl -o - | %file-check %s +// +// CHECK: hl.var @ew, +extern int __attribute__((weak)) ew; +// CHECK: hl.var @wundef, +int __attribute__((weak)) wundef; +// CHECK: hl.var @wdef, +int __attribute__((weak)) wdef = 5; +// CHECK: hl.var @ewdef, +extern int __attribute__((weak)) ewdef = 5; +// CHECK: hl.var @edef, +extern int edef = 5; +// CHECK: hl.var @undef, +int undef; +// CHECK: hl.var @def, +int def = 5; diff --git a/test/vast/Dialect/HighLevel/indirect-call-a.c b/test/vast/Dialect/HighLevel/indirect-call-a.c index acbea2101a..cb71b3412d 100644 --- a/test/vast/Dialect/HighLevel/indirect-call-a.c +++ b/test/vast/Dialect/HighLevel/indirect-call-a.c @@ -3,7 +3,7 @@ // CHECK: hl.typedef @ck_rv_t : !hl.long< unsigned > typedef unsigned long ck_rv_t; -// CHECK: hl.var @global_lock sc_static : !hl.lvalue> +// CHECK: hl.var @global_lock, sc_static : !hl.lvalue> static void *global_lock = 0; // CHECK: hl.typedef @ck_createmutex_t : !hl.ptr>>) -> (!hl.elaborated>)>>> @@ -33,19 +33,19 @@ struct ck_c_initialize_args // CHECK: hl.typedef @CK_C_INITIALIZE_ARGS_PTR : !hl.ptr>> typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; -// CHECK: hl.var @global_locking sc_static : !hl.lvalue>> +// CHECK: hl.var @global_locking, sc_static : !hl.lvalue>> static CK_C_INITIALIZE_ARGS_PTR global_locking; // CHECK: hl.func @sc_pkcs11_lock {{.*}} () -> !hl.long long sc_pkcs11_lock(void) { - // CHECK: [[V1:%[0-9]+]] = hl.globref @global_locking : !hl.lvalue>> + // CHECK: [[V1:%[0-9]+]] = hl.ref @global_locking : !hl.lvalue>> // CHECK: [[V2:%[0-9]+]] = hl.implicit_cast [[V1]] LValueToRValue : !hl.lvalue>> -> !hl.elaborated> // CHECK: hl.cond.yield [[V2]] : !hl.elaborated> if (global_locking) { // CHECK: [[M:%[0-9]+]] = hl.member [[X:%[0-9]+]] at @lock_mutex // CHECK: [[C:%[0-9]+]] = hl.implicit_cast [[M]] LValueToRValue : !hl.lvalue>> -> !hl.elaborated> - // CHECK: [[G:%[0-9]+]] = hl.globref @global_lock : !hl.lvalue> + // CHECK: [[G:%[0-9]+]] = hl.ref @global_lock : !hl.lvalue> // CHECK: [[A:%[0-9]+]] = hl.implicit_cast [[G]] LValueToRValue : !hl.lvalue> -> !hl.ptr // CHECK: hl.indirect_call [[C]] : !hl.elaborated>([[A]]) : (!hl.ptr) -> !hl.elaborated> while (global_locking->lock_mutex(global_lock) != 0); diff --git a/test/vast/Dialect/HighLevel/literals-a.c b/test/vast/Dialect/HighLevel/literals-a.c index 06bd07f427..6712dcbce6 100644 --- a/test/vast/Dialect/HighLevel/literals-a.c +++ b/test/vast/Dialect/HighLevel/literals-a.c @@ -1,37 +1,37 @@ // // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s // // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - -// CHECK: hl.var @li : !hl.lvalue> +// CHECK: hl.var @li, : !hl.lvalue> // CHECK: hl.const #core.integer<10> : !hl.int const int li = 10; -// CHECK: hl.var @lui : !hl.lvalue> +// CHECK: hl.var @lui, : !hl.lvalue> // CHECK: hl.const #core.integer<10> : !hl.int< unsigned > const unsigned int lui = 10u; -// CHECK: hl.var @ll : !hl.lvalue> +// CHECK: hl.var @ll, : !hl.lvalue> // CHECK: hl.const #core.integer<10> : !hl.long const long ll = 10l; -// CHECK: hl.var @lf : !hl.lvalue> +// CHECK: hl.var @lf, : !hl.lvalue> // CHECK: hl.const #core.float<5.000000e-01> : !hl.float const float lf = 0.5f; -// CHECK: hl.var @ld : !hl.lvalue> +// CHECK: hl.var @ld, : !hl.lvalue> // CHECK: hl.const #core.float<5.000000e-01> : !hl.double const double ld = 0.5; -// CHECK: hl.var @lc : !hl.lvalue> +// CHECK: hl.var @lc, : !hl.lvalue> // CHECK: hl.const #core.integer<97> : !hl.int // CHECK: IntegralCast : !hl.int -> !hl.char const char lc = 'a'; -// CHECK: hl.var @null : !hl.lvalue>> +// CHECK: hl.var @null, : !hl.lvalue>> // CHECK: hl.const #core.integer<0> : !hl.int // CHECK: NullToPointer : !hl.int -> !hl.ptr> const void *null = 0; -// CHECK: hl.var @lb : !hl.lvalue> +// CHECK: hl.var @lb, : !hl.lvalue> // CHECK: hl.const #core.integer<1> : !hl.int // CHECK: IntegralToBoolean : !hl.int -> !hl.bool const _Bool lb = 1; @@ -39,17 +39,17 @@ const _Bool lb = 1; #define SCHAR_MIN (-128) #define SCHAR_MAX 127 -// CHECK: hl.var @scmin : !hl.lvalue> +// CHECK: hl.var @scmin, : !hl.lvalue> // CHECK: hl.const #core.integer<128> : !hl.int // CHECK: hl.minus const char scmin = SCHAR_MIN; -// CHECK: hl.var @scmax : !hl.lvalue> +// CHECK: hl.var @scmax, : !hl.lvalue> // CHECK: hl.const #core.integer<127> : !hl.int const char scmax = SCHAR_MAX; #define UCHAR_MAX 255 -// CHECK: hl.var @ucmax : !hl.lvalue> +// CHECK: hl.var @ucmax, : !hl.lvalue> // CHECK: hl.const #core.integer<255> : !hl.int const unsigned char ucmax = UCHAR_MAX; diff --git a/test/vast/Dialect/HighLevel/pointers-a.c b/test/vast/Dialect/HighLevel/pointers-a.c index 9f8f6fe3d4..92763e699a 100644 --- a/test/vast/Dialect/HighLevel/pointers-a.c +++ b/test/vast/Dialect/HighLevel/pointers-a.c @@ -1,47 +1,47 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - -// CHECK: hl.var @vp : !hl.lvalue> +// CHECK: hl.var @vp, : !hl.lvalue> void * vp = 0; -// CHECK: hl.var @vpp : !hl.lvalue>> +// CHECK: hl.var @vpp, : !hl.lvalue>> void ** vpp = 0; -// CHECK: hl.var @ip : !hl.lvalue> +// CHECK: hl.var @ip, : !hl.lvalue> int * ip = 0; -// CHECK: hl.var @icp : !hl.lvalue>> +// CHECK: hl.var @icp, : !hl.lvalue>> int const * icp = 0; -// CHECK: hl.var @cip : !hl.lvalue>> +// CHECK: hl.var @cip, : !hl.lvalue>> const int * cip = 0; -// CHECK: hl.var @ipc : !hl.lvalue> +// CHECK: hl.var @ipc, : !hl.lvalue> int * const ipc = 0; -// CHECK: hl.var @icpc : !hl.lvalue, const >> +// CHECK: hl.var @icpc, : !hl.lvalue, const >> int const * const icpc = 0; -// CHECK: hl.var @cipc : !hl.lvalue, const >> +// CHECK: hl.var @cipc, : !hl.lvalue, const >> const int * const cipc = 0; -// CHECK: hl.var @ipp : !hl.lvalue>> +// CHECK: hl.var @ipp, : !hl.lvalue>> int ** ipp = 0; -// CHECK: hl.var @ippc : !hl.lvalue, const >> +// CHECK: hl.var @ippc, : !hl.lvalue, const >> int ** const ippc = 0; -// CHECK: hl.var @ipcp : !hl.lvalue>> +// CHECK: hl.var @ipcp, : !hl.lvalue>> int * const * ipcp = 0; -// CHECK: hl.var @icpp : !hl.lvalue>>> +// CHECK: hl.var @icpp, : !hl.lvalue>>> int const ** icpp = 0; -// CHECK: hl.var @ipcpc : !hl.lvalue, const >> +// CHECK: hl.var @ipcpc, : !hl.lvalue, const >> int * const * const ipcpc = 0; -// CHECK: hl.var @ippp : !hl.lvalue>>> +// CHECK: hl.var @ippp, : !hl.lvalue>>> int *** ippp = 0; -// CHECK: hl.var @uip : !hl.lvalue>> +// CHECK: hl.var @uip, : !hl.lvalue>> unsigned int *uip = 0; diff --git a/test/vast/Dialect/HighLevel/pointers-b.c b/test/vast/Dialect/HighLevel/pointers-b.c index 3d026216c4..724b3f3c2a 100644 --- a/test/vast/Dialect/HighLevel/pointers-b.c +++ b/test/vast/Dialect/HighLevel/pointers-b.c @@ -1,33 +1,33 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - -// CHECK: hl.var @p : !hl.lvalue> -// CHECK: hl.var @pp : !hl.lvalue>> +// CHECK: hl.var @p, : !hl.lvalue> +// CHECK: hl.var @pp, : !hl.lvalue>> float *p, **pp; // p is a pointer to float // pp is a pointer to a pointer to float -// CHECK: hl.var @fp : !hl.lvalue) -> (!hl.int)>>>> +// CHECK: hl.var @fp, : !hl.lvalue) -> (!hl.int)>>>> int (*fp)(int); // fp is a pointer to function with type int(int) -// CHECK: hl.var @pc : !hl.lvalue>> +// CHECK: hl.var @pc, : !hl.lvalue>> int n; const int * pc = &n; // pc is a non-const pointer to a const int -// CHECK: hl.var @cp : !hl.lvalue> +// CHECK: hl.var @cp, : !hl.lvalue> int * const cp = &n; // cp is a const pointer to a non-const int -// CHECK: hl.var @pcp : !hl.lvalue>> +// CHECK: hl.var @pcp, : !hl.lvalue>> int * const * pcp = &cp; // non-const pointer to const pointer to non-const int -// CHECK: hl.var @np : !hl.lvalue> +// CHECK: hl.var @np, : !hl.lvalue> int *np = &n; // pointer to int -// CHECK: hl.var @npp : !hl.lvalue>> +// CHECK: hl.var @npp, : !hl.lvalue>> int *const *npp = &np; // non-const pointer to const pointer to non-const int int a[2]; -// CHECK: hl.var @ap : !hl.lvalue>>> +// CHECK: hl.var @ap, : !hl.lvalue>>> int (*ap)[2] = &a; // pointer to array of int struct S { int n; } s = {1}; -// CHECK: hl.var @sp : !hl.lvalue> +// CHECK: hl.var @sp, : !hl.lvalue> int* sp = &s.n; // pointer to the int that is a member of s diff --git a/test/vast/Dialect/HighLevel/pointers-c.c b/test/vast/Dialect/HighLevel/pointers-c.c index 3abf01435f..736e9dc552 100644 --- a/test/vast/Dialect/HighLevel/pointers-c.c +++ b/test/vast/Dialect/HighLevel/pointers-c.c @@ -1,12 +1,12 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - -// CHECK: hl.var @p : !hl.lvalue> +// CHECK: hl.var @p, : !hl.lvalue> // CHECK: ArrayToPointerDecay : !hl.lvalue> -> !hl.ptr int a[2]; int *p = a; // pointer to a[0] -// CHECK: hl.var @row : !hl.lvalue>>> +// CHECK: hl.var @row, : !hl.lvalue>>> // CHECK: ArrayToPointerDecay : !hl.lvalue>> -> !hl.ptr> int b[3][3]; int (*row)[3] = b; // pointer to b[0] diff --git a/test/vast/Dialect/HighLevel/pointers-d.c b/test/vast/Dialect/HighLevel/pointers-d.c index 81ece79dfb..062b9825ed 100644 --- a/test/vast/Dialect/HighLevel/pointers-d.c +++ b/test/vast/Dialect/HighLevel/pointers-d.c @@ -2,11 +2,11 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - void f(int); -// CHECK: hl.var @pf1 : !hl.lvalue) -> (!hl.void)>>>> +// CHECK: hl.var @pf1, : !hl.lvalue) -> (!hl.void)>>>> // CHECK: [[R:%[0-9]+]] = hl.funcref @f : !core.fn<(!hl.lvalue) -> (!hl.void)> // CHECK: hl.addressof [[R]] : !core.fn<(!hl.lvalue) -> (!hl.void)> -> !hl.ptr) -> (!hl.void)>> void (*pf1)(int) = &f; -// CHECK: hl.var @pf2 : !hl.lvalue) -> (!hl.void)>>>> +// CHECK: hl.var @pf2, : !hl.lvalue) -> (!hl.void)>>>> // CHECK: [[R:%[0-9]+]] = hl.funcref @f : !core.fn<(!hl.lvalue) -> (!hl.void)> // CHECK: hl.implicit_cast [[R]] FunctionToPointerDecay : !core.fn<(!hl.lvalue) -> (!hl.void)> -> !hl.ptr) -> (!hl.void)>> void (*pf2)(int) = f; // same as &f diff --git a/test/vast/Dialect/HighLevel/qualifiers-c.cpp b/test/vast/Dialect/HighLevel/qualifiers-c.cpp index 81a53d598a..4791b3be2d 100644 --- a/test/vast/Dialect/HighLevel/qualifiers-c.cpp +++ b/test/vast/Dialect/HighLevel/qualifiers-c.cpp @@ -1,50 +1,50 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - -// CHECK: hl.var @p : !hl.lvalue> +// CHECK: hl.var @p, : !hl.lvalue> void *p; -// CHECK: hl.var @i : !hl.lvalue> +// CHECK: hl.var @i, : !hl.lvalue> int *i; -// CHECK: hl.var @u : !hl.lvalue>> +// CHECK: hl.var @u, : !hl.lvalue>> unsigned *u; -// CHECK: hl.var @s : !hl.lvalue> +// CHECK: hl.var @s, : !hl.lvalue> signed *s; -// CHECK: hl.var @ui : !hl.lvalue>> +// CHECK: hl.var @ui, : !hl.lvalue>> unsigned int *ui; -// CHECK: hl.var @us : !hl.lvalue>> +// CHECK: hl.var @us, : !hl.lvalue>> unsigned short *us; -// CHECK: hl.var @ci : !hl.lvalue>> +// CHECK: hl.var @ci, : !hl.lvalue>> const int *ci = 0; -// CHECK: hl.var @cui : !hl.lvalue>> +// CHECK: hl.var @cui, : !hl.lvalue>> const unsigned *cui = 0; -// CHECK: hl.var @vi : !hl.lvalue>> +// CHECK: hl.var @vi, : !hl.lvalue>> volatile int *vi; -// CHECK: hl.var @vui : !hl.lvalue>> +// CHECK: hl.var @vui, : !hl.lvalue>> volatile unsigned *vui; -// CHECK: hl.var @cvi : !hl.lvalue>> +// CHECK: hl.var @cvi, : !hl.lvalue>> const volatile int *cvi = 0; -// CHECK: hl.var @cvui : !hl.lvalue>> +// CHECK: hl.var @cvui, : !hl.lvalue>> const volatile unsigned int *cvui = 0U; -// CHECK: hl.var @b : !hl.lvalue> +// CHECK: hl.var @b, : !hl.lvalue> bool *b; -// CHECK: hl.var @vb : !hl.lvalue>> +// CHECK: hl.var @vb, : !hl.lvalue>> volatile bool *vb; -// CHECK: hl.var @cb : !hl.lvalue>> +// CHECK: hl.var @cb, : !hl.lvalue>> const bool *cb = 0; -// CHECK: hl.var @cvb : !hl.lvalue>> +// CHECK: hl.var @cvb, : !hl.lvalue>> const volatile bool *cvb = 0; diff --git a/test/vast/Dialect/HighLevel/qualifiers-e.c b/test/vast/Dialect/HighLevel/qualifiers-e.c index 9a54f36a9c..86cf638cf3 100644 --- a/test/vast/Dialect/HighLevel/qualifiers-e.c +++ b/test/vast/Dialect/HighLevel/qualifiers-e.c @@ -1,14 +1,14 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - -// CHECK: hl.var @ia : !hl.lvalue> +// CHECK: hl.var @ia, : !hl.lvalue> int ia[10]; -// CHECK: hl.var @cia : !hl.lvalue>> +// CHECK: hl.var @cia, : !hl.lvalue>> const int cia[10]; -// CHECK: hl.var @via : !hl.lvalue>> +// CHECK: hl.var @via, : !hl.lvalue>> volatile int via[10]; -// CHECK: hl.var @cvia : !hl.lvalue>> +// CHECK: hl.var @cvia, : !hl.lvalue>> const volatile int cvia[10]; diff --git a/test/vast/Dialect/HighLevel/qualifiers-g.c b/test/vast/Dialect/HighLevel/qualifiers-g.c index 19e9b2fb6c..1abc45a971 100644 --- a/test/vast/Dialect/HighLevel/qualifiers-g.c +++ b/test/vast/Dialect/HighLevel/qualifiers-g.c @@ -1,8 +1,8 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - -// CHECK: hl.var @a : !hl.lvalue> -// CHECK: hl.var @b : !hl.lvalue> +// CHECK: hl.var @a, : !hl.lvalue> +// CHECK: hl.var @b, : !hl.lvalue> float * restrict a, * restrict b; // CHECK: @f {{.*}} (!hl.lvalue, !hl.lvalue>, !hl.lvalue>) diff --git a/test/vast/Dialect/HighLevel/qualifiers-h.c b/test/vast/Dialect/HighLevel/qualifiers-h.c index 283f017e66..35adb44739 100644 --- a/test/vast/Dialect/HighLevel/qualifiers-h.c +++ b/test/vast/Dialect/HighLevel/qualifiers-h.c @@ -4,26 +4,26 @@ // CHECK: hl.enum @e : !hl.int< unsigned > enum e { a, b, c }; -// CHECK: hl.var @v : !hl.lvalue>> +// CHECK: hl.var @v, : !hl.lvalue>> enum e v; -// CHECK: hl.var @cv : !hl.lvalue, const >> +// CHECK: hl.var @cv, : !hl.lvalue, const >> const enum e cv; -// CHECK: hl.var @cvv : !hl.lvalue, const, volatile >> +// CHECK: hl.var @cvv, : !hl.lvalue, const, volatile >> const volatile enum e cvv; // CHECK: hl.typedef @def : !hl.elaborated> typedef enum e def; -// CHECK: hl.var @d : !hl.lvalue>> +// CHECK: hl.var @d, : !hl.lvalue>> def d; -// CHECK: hl.var @cd : !hl.lvalue, const >> +// CHECK: hl.var @cd, : !hl.lvalue, const >> const def cd; -// CHECK: hl.var @vd : !hl.lvalue, volatile >> +// CHECK: hl.var @vd, : !hl.lvalue, volatile >> volatile def vd; -// CHECK: hl.var @cvd : !hl.lvalue, const, volatile >> +// CHECK: hl.var @cvd, : !hl.lvalue, const, volatile >> const volatile def cvd; diff --git a/test/vast/Dialect/HighLevel/qualifiers-i.c b/test/vast/Dialect/HighLevel/qualifiers-i.c index b40c0248e4..93f5c437df 100644 --- a/test/vast/Dialect/HighLevel/qualifiers-i.c +++ b/test/vast/Dialect/HighLevel/qualifiers-i.c @@ -4,26 +4,26 @@ // CHECK: hl.union @u union u { int i; double d; }; -// CHECK: hl.var @v : !hl.lvalue>> +// CHECK: hl.var @v, : !hl.lvalue>> union u v; -// CHECK: hl.var @cv : !hl.lvalue, const >> +// CHECK: hl.var @cv, : !hl.lvalue, const >> const union u cv; -// CHECK: hl.var @cvv : !hl.lvalue, const, volatile >> +// CHECK: hl.var @cvv, : !hl.lvalue, const, volatile >> const volatile union u cvv; // CHECK: hl.typedef @e : !hl.elaborated> typedef union u e; -// CHECK: hl.var @v : !hl.lvalue>> +// CHECK: hl.var @v, : !hl.lvalue>> e v; -// CHECK: hl.var @cv : !hl.lvalue, const >> +// CHECK: hl.var @cv, : !hl.lvalue, const >> const e cv; -// CHECK: hl.var @vv : !hl.lvalue, volatile >> +// CHECK: hl.var @vv, : !hl.lvalue, volatile >> volatile e vv; -// CHECK: hl.var @cvv : !hl.lvalue, const, volatile >> +// CHECK: hl.var @cvv, : !hl.lvalue, const, volatile >> const volatile e cvv; diff --git a/test/vast/Dialect/HighLevel/qualifiers-j.c b/test/vast/Dialect/HighLevel/qualifiers-j.c index 3374566e38..2fed1f8368 100644 --- a/test/vast/Dialect/HighLevel/qualifiers-j.c +++ b/test/vast/Dialect/HighLevel/qualifiers-j.c @@ -1,11 +1,11 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - -// CHECK: hl.var @fp : !hl.lvalue) -> (!hl.int)>>>> +// CHECK: hl.var @fp, : !hl.lvalue) -> (!hl.int)>>>> int (*fp) (int); -// CHECK: hl.var @cfp : !hl.lvalue) -> (!hl.int< const >)>>>> +// CHECK: hl.var @cfp, : !hl.lvalue) -> (!hl.int< const >)>>>> const int (*cfp)(int); -// CHECK: hl.var @fpc : !hl.lvalue>) -> (!hl.int)>>>> +// CHECK: hl.var @fpc, : !hl.lvalue>) -> (!hl.int)>>>> int (*fpc)(const int); diff --git a/test/vast/Dialect/HighLevel/quirks-i.c b/test/vast/Dialect/HighLevel/quirks-i.c index 9afc2d3df9..69402f3ac2 100644 --- a/test/vast/Dialect/HighLevel/quirks-i.c +++ b/test/vast/Dialect/HighLevel/quirks-i.c @@ -18,7 +18,7 @@ struct lots_of_inits { int w[3]; }; -// CHECK: hl.var @init : !hl.lvalue>> +// CHECK: hl.var @init, : !hl.lvalue>> struct lots_of_inits init = { // CHECK: [[A:%[0-9]+]] = hl.const #core.integer<1> : !hl.int // CHECK: [[B:%[0-9]+]] = hl.const #core.integer<2> : !hl.int @@ -34,7 +34,7 @@ struct lots_of_inits init = { {{1, 2}, {3, 4}}, {5, 6, 7} }; -// CHECK: hl.var @flat_init : !hl.lvalue>> +// CHECK: hl.var @flat_init, : !hl.lvalue>> struct lots_of_inits flat_init = { // CHECK: [[A:%[0-9]+]] = hl.const #core.integer<1> : !hl.int diff --git a/test/vast/Dialect/HighLevel/quirks-k.c b/test/vast/Dialect/HighLevel/quirks-k.c index 3f8b0e178e..f7885471be 100644 --- a/test/vast/Dialect/HighLevel/quirks-k.c +++ b/test/vast/Dialect/HighLevel/quirks-k.c @@ -3,5 +3,5 @@ // adapted from https://gist.github.com/fay59/5ccbe684e6e56a7df8815c3486568f01 -// CHECK: hl.var @foo sc_extern : !hl.lvalue +// CHECK: hl.var @foo, sc_extern : !hl.lvalue extern void foo; diff --git a/test/vast/Dialect/HighLevel/quirks-n.c b/test/vast/Dialect/HighLevel/quirks-n.c index d67ab60f1a..a541e6a3ab 100644 --- a/test/vast/Dialect/HighLevel/quirks-n.c +++ b/test/vast/Dialect/HighLevel/quirks-n.c @@ -12,9 +12,9 @@ unsigned int typedef u32; // CHECK: hl.typedef @baz : !hl.elaborated, const > struct foo { int bar; } const typedef baz; -// CHECK: hl.var @a : !hl.lvalue>> +// CHECK: hl.var @a, : !hl.lvalue>> s16 a; -// CHECK: hl.var @b : !hl.lvalue>> +// CHECK: hl.var @b, : !hl.lvalue>> u32 b; -// CHECK: hl.var @c : !hl.lvalue>> +// CHECK: hl.var @c, : !hl.lvalue>> baz c; diff --git a/test/vast/Dialect/HighLevel/storage-a.c b/test/vast/Dialect/HighLevel/storage-a.c index 823b7afd95..73775514fa 100644 --- a/test/vast/Dialect/HighLevel/storage-a.c +++ b/test/vast/Dialect/HighLevel/storage-a.c @@ -1,22 +1,22 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - -// CHECK: hl.var @i : !hl.lvalue +// CHECK: hl.var @i, : !hl.lvalue int i; -// CHECKL: hl.var @ei sc_extern : !hl.lvalue +// CHECKL: hl.var @ei, sc_extern : !hl.lvalue extern int ei; -// CHECK: hl.var @si sc_static : !hl.lvalue +// CHECK: hl.var @si, sc_static : !hl.lvalue static int si = 0; -// CHECK: hl.var @ti tsc_c_thread : !hl.lvalue +// CHECK: hl.var @ti, tsc_c_thread : !hl.lvalue _Thread_local int ti; -// CHECK: hl.var @tei sc_extern tsc_c_thread +// CHECK: hl.var @tei, sc_extern tsc_c_thread _Thread_local extern int tei; -// CHECK: hl.var @sti sc_static tsc_c_thread +// CHECK: hl.var @sti, sc_static tsc_c_thread _Thread_local static int sti = 0; void foo() { diff --git a/test/vast/Dialect/HighLevel/string-a.c b/test/vast/Dialect/HighLevel/string-a.c index bb02d4d048..07c47b8a77 100644 --- a/test/vast/Dialect/HighLevel/string-a.c +++ b/test/vast/Dialect/HighLevel/string-a.c @@ -1,7 +1,7 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - -// CHECK: hl.var @gstr : !hl.lvalue>> +// CHECK: hl.var @gstr, : !hl.lvalue>> // CHECK: hl.const "global" : !hl.lvalue> // CHECK: ArrayToPointerDecay : !hl.lvalue> -> !hl.ptr const char *gstr = "global"; diff --git a/test/vast/Dialect/HighLevel/string-b.c b/test/vast/Dialect/HighLevel/string-b.c index 40d680aed6..e3aa570e72 100644 --- a/test/vast/Dialect/HighLevel/string-b.c +++ b/test/vast/Dialect/HighLevel/string-b.c @@ -1,7 +1,7 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %file-check %s // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o %t && %vast-opt %t | diff -B %t - -// CHECK: hl.var @gstr : !hl.lvalue>> +// CHECK: hl.var @gstr, : !hl.lvalue>> // CHECK: hl.const "global\0A" : !hl.lvalue> // CHECK: ArrayToPointerDecay : !hl.lvalue> -> !hl.ptr const char *gstr = "global\n"; diff --git a/test/vast/Dialect/HighLevel/struct-a.c b/test/vast/Dialect/HighLevel/struct-a.c index b576920141..c29051c364 100644 --- a/test/vast/Dialect/HighLevel/struct-a.c +++ b/test/vast/Dialect/HighLevel/struct-a.c @@ -12,7 +12,7 @@ struct pair { int a, b; }; -// CHECK: hl.var @p : !hl.lvalue>> +// CHECK: hl.var @p, : !hl.lvalue>> struct pair p; struct forward; @@ -33,7 +33,7 @@ typedef struct wrap { int v; } wrap_t; -// CHECK: hl.var @w : !hl.lvalue>> +// CHECK: hl.var @w, : !hl.lvalue>> wrap_t w; // CHECK: hl.struct @compound : { diff --git a/test/vast/Dialect/HighLevel/struct-c.c b/test/vast/Dialect/HighLevel/struct-c.c index b66cafd24a..c1f91004b6 100644 --- a/test/vast/Dialect/HighLevel/struct-c.c +++ b/test/vast/Dialect/HighLevel/struct-c.c @@ -4,7 +4,7 @@ // CHECK: hl.struct @"[[N:anonymous\[[0-9]+\]]]" : { // CHECK: hl.field @data : !hl.int // CHECK: } -// CHECK: hl.var @named : !hl.lvalue>> +// CHECK: hl.var @named, : !hl.lvalue>> struct { int data; } named; diff --git a/test/vast/Dialect/HighLevel/struct-f.c b/test/vast/Dialect/HighLevel/struct-f.c index 59706e9f6b..0962f22a12 100644 --- a/test/vast/Dialect/HighLevel/struct-f.c +++ b/test/vast/Dialect/HighLevel/struct-f.c @@ -8,7 +8,7 @@ struct X {}; // CHECK: hl.typedef @X : !hl.elaborated> typedef struct Y {} X; -// CHECK: hl.var @x : !hl.lvalue>> +// CHECK: hl.var @x, : !hl.lvalue>> // TODO: this is elaborated "X" struct X x; diff --git a/test/vast/Dialect/HighLevel/union-a.c b/test/vast/Dialect/HighLevel/union-a.c index bf7453af19..ac50c2ac04 100644 --- a/test/vast/Dialect/HighLevel/union-a.c +++ b/test/vast/Dialect/HighLevel/union-a.c @@ -6,7 +6,7 @@ // CHECK: hl.field @u16 : !hl.array<2, !hl.short< unsigned >> // CHECK: hl.field @u8 : !hl.char< unsigned > // CHECK: } -// CHECK: hl.var @u : !hl.lvalue> +// CHECK: hl.var @u, : !hl.lvalue> union u { unsigned int u32; unsigned short u16[2]; diff --git a/test/vast/Dialect/HighLevel/union-b.c b/test/vast/Dialect/HighLevel/union-b.c index 496ba5e851..a2376d283f 100644 --- a/test/vast/Dialect/HighLevel/union-b.c +++ b/test/vast/Dialect/HighLevel/union-b.c @@ -19,11 +19,11 @@ struct v { // CHECK: hl.field @"[[N5:anonymous\[[0-9]+\]]]" : !hl.record<@"[[N1]]"> // CHECK: hl.field @m : !hl.int int m; -// CHECK: hl.var @v1 : !hl.lvalue>> +// CHECK: hl.var @v1, : !hl.lvalue>> } v1; int main() { - // CHECK: [[V1:%[0-9]+]] = hl.globref @v1 : !hl.lvalue>> + // CHECK: [[V1:%[0-9]+]] = hl.ref @v1 : !hl.lvalue>> // CHECK: [[V2:%[0-9]+]] = hl.member [[V1]] at @"[[N5]]" : !hl.lvalue>> -> !hl.lvalue> // CHECK: [[V3:%[0-9]+]] = hl.member [[V2]] at @"[[N3]]" : !hl.lvalue> -> !hl.lvalue> @@ -32,7 +32,7 @@ int main() { // CHECK: hl.assign [[C]] to [[V4]] : !hl.int, !hl.lvalue -> !hl.int v1.i = 2; - // CHECK: [[V1:%[0-9]+]] = hl.globref @v1 : !hl.lvalue>> + // CHECK: [[V1:%[0-9]+]] = hl.ref @v1 : !hl.lvalue>> // CHECK: [[V2:%[0-9]+]] = hl.member [[V1]] at @"[[N5]]" : !hl.lvalue>> -> !hl.lvalue> // CHECK: [[V3:%[0-9]+]] = hl.member [[V2]] at @w : !hl.lvalue> -> !hl.lvalue>> // CHECK: [[V4:%[0-9]+]] = hl.member [[V3]] at @k : !hl.lvalue>> -> !hl.lvalue diff --git a/test/vast/Transform/HL/LowerTypedefs/var-a.c b/test/vast/Transform/HL/LowerTypedefs/var-a.c index a6bdab6dd6..3a80c90643 100644 --- a/test/vast/Transform/HL/LowerTypedefs/var-a.c +++ b/test/vast/Transform/HL/LowerTypedefs/var-a.c @@ -2,15 +2,15 @@ typedef int INT; -// CHECK: hl.var @a : !hl.lvalue +// CHECK: hl.var @a, : !hl.lvalue INT a = 0; typedef INT IINT; -// CHECK: hl.var @b : !hl.lvalue +// CHECK: hl.var @b, : !hl.lvalue IINT b = 0; typedef IINT IIINT; -// CHECK: hl.var @c : !hl.lvalue +// CHECK: hl.var @c, : !hl.lvalue IIINT c = 0; diff --git a/test/vast/Transform/HL/LowerTypes/array-a.c b/test/vast/Transform/HL/LowerTypes/array-a.c index 817c986e07..c22e0012bb 100644 --- a/test/vast/Transform/HL/LowerTypes/array-a.c +++ b/test/vast/Transform/HL/LowerTypes/array-a.c @@ -1,22 +1,22 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %vast-opt --vast-hl-lower-types | %file-check %s -// CHECK: hl.var @ai : !hl.lvalue> +// CHECK: hl.var @ai, : !hl.lvalue> int ai[10]; -// CHECK: hl.var @aci : !hl.lvalue> +// CHECK: hl.var @aci, : !hl.lvalue> const int aci[5]; -// CHECK: hl.var @avi : !hl.lvalue> +// CHECK: hl.var @avi, : !hl.lvalue> volatile int avi[5]; -// CHECK: hl.var @acvi : !hl.lvalue> +// CHECK: hl.var @acvi, : !hl.lvalue> const volatile int acvi[5]; -// CHECK: hl.var @acvui : !hl.lvalue> +// CHECK: hl.var @acvui, : !hl.lvalue> const volatile unsigned int acvui[5]; -// CHECK: hl.var @af : !hl.lvalue> +// CHECK: hl.var @af, : !hl.lvalue> float af[10]; -// CHECK: hl.var @a3d : !hl.lvalue>>> +// CHECK: hl.var @a3d, : !hl.lvalue>>> float a3d[2][4][3]; diff --git a/test/vast/Transform/HL/LowerTypes/array-b.c b/test/vast/Transform/HL/LowerTypes/array-b.c index c10980a013..35b3277d69 100644 --- a/test/vast/Transform/HL/LowerTypes/array-b.c +++ b/test/vast/Transform/HL/LowerTypes/array-b.c @@ -1,4 +1,4 @@ // RUN: %vast-cc1 -vast-emit-mlir=hl %s -o - | %vast-opt --vast-hl-lower-types | %file-check %s -// CHECK: hl.var @a sc_extern : !hl.lvalue> +// CHECK: hl.var @a, sc_extern : !hl.lvalue> extern int a[]; diff --git a/test/vast/Transform/HL/LowerTypes/fn-ptr-a.c b/test/vast/Transform/HL/LowerTypes/fn-ptr-a.c index be75588a2d..97cb06d871 100644 --- a/test/vast/Transform/HL/LowerTypes/fn-ptr-a.c +++ b/test/vast/Transform/HL/LowerTypes/fn-ptr-a.c @@ -10,7 +10,7 @@ void * malloc ( unsigned long __size ); curl_malloc_callback Curl_cmalloc = ( curl_malloc_callback ) malloc ; // LTYPES: hl.typedef @curl_malloc_callback : !hl.ptr) -> (!hl.ptr)>> -// LTYPES: hl.var @Curl_cmalloc : !hl.lvalue>> = { +// LTYPES: hl.var @Curl_cmalloc, : !hl.lvalue>> = { -// LTYPEDEFS: hl.var @Curl_cmalloc sc_extern : !hl.lvalue) -> (!hl.ptr)>>> -// LTYPEDEFS: hl.var @Curl_cmalloc : !hl.lvalue) -> (!hl.ptr)>>> = { +// LTYPEDEFS: hl.var @Curl_cmalloc, sc_extern : !hl.lvalue) -> (!hl.ptr)>>> +// LTYPEDEFS: hl.var @Curl_cmalloc, : !hl.lvalue) -> (!hl.ptr)>>> = {