Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for cells with non-local storage #730

Merged
merged 23 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7e9ada2
treewide: Move storage classes from hl to core.
Jezurko Sep 23, 2024
66e5138
core: Add DeclStorageInterface.
Jezurko Sep 23, 2024
6b73ddc
hl: Make VarDeclOp use DeclStorageInterface instead of local methods.
Jezurko Sep 23, 2024
9f0b446
core: Remove unnecessary includes from DeclStorageInterface.
Jezurko Sep 24, 2024
19f60a9
treewide: Add declaration storage information ll.cell.
Jezurko Sep 24, 2024
e5ab6e8
treewide: Replace GlobalRefOp with DeclRefOp.
Jezurko Sep 24, 2024
c050e94
test: Replace hl.globref with hl.ref.
Jezurko Sep 24, 2024
9e05620
conv:tomem: Mark DeclRefs to globals as legal.
Jezurko Sep 24, 2024
d563545
conv:irstollvm: Simplify global vardecl visitor.
Jezurko Sep 24, 2024
d113c20
hl: Enable default constructors of VarDeclOp.
Jezurko Sep 24, 2024
6c4f4f1
conv:tomem: Add EvictStaticLocals pass.
Jezurko Sep 24, 2024
2fcf69d
conv:evictstatic: Explicitely save decl context to attribute when moved.
Jezurko Sep 25, 2024
64cdda7
core: Remove obsolete Impl helpers.
Jezurko Sep 25, 2024
dbab3b6
core: Add forward-declaring linkage helper file.
Jezurko Sep 25, 2024
6d119c6
core: Add function translating our linkage to llvm linkage.
Jezurko Sep 25, 2024
1cf7429
hl: Add optional linakge attribute for global variables.
Jezurko Sep 25, 2024
feb3a65
conv:irstollvm: Add handling of linakge information.
Jezurko Sep 25, 2024
37f6f2d
conv:evictstatic: Add linkage to variable moved to global scope.
Jezurko Sep 25, 2024
d452285
test: Add evict-static-locals to the list of passes.
Jezurko Sep 25, 2024
46554b5
test:conv: Add test for lowering of static local.
Jezurko Sep 25, 2024
bde05ff
test: Add missing linkage to global variables.
Jezurko Sep 25, 2024
6adec31
cg: Emit external weak linakge for global variables.
Jezurko Oct 4, 2024
c9e72dd
test: Add test for external and weak linakge of global variables.
Jezurko Oct 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/vast/Conversion/Passes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
10 changes: 10 additions & 0 deletions include/vast/Conversion/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -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`.";

Expand Down
8 changes: 8 additions & 0 deletions include/vast/Dialect/Core/CoreAttributes.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2022-present, Trail of Bits, Inc.

Check notice on line 1 in include/vast/Dialect/Core/CoreAttributes.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter (18, 22.04)

Run clang-format on include/vast/Dialect/Core/CoreAttributes.hpp

File include/vast/Dialect/Core/CoreAttributes.hpp does not conform to Custom style guidelines. (lines 36)

#pragma once

Expand Down Expand Up @@ -28,4 +28,12 @@

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
106 changes: 106 additions & 0 deletions include/vast/Dialect/Core/CoreAttributes.td
Original file line number Diff line number Diff line change
Expand Up @@ -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<Core_StorageClassAttr> 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<Core_TSCAttr> 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<Core_StorageDurationAttr> 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<Core_DeclContextAttr> 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
13 changes: 1 addition & 12 deletions include/vast/Dialect/Core/Func.td
Original file line number Diff line number Diff line change
Expand Up @@ -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)">,
Expand Down
1 change: 1 addition & 0 deletions include/vast/Dialect/Core/Interfaces/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
add_vast_op_interface(DeclStorageInterface)
add_vast_op_interface(TypeDefinitionInterface)

add_vast_op_interface(SymbolInterface)
Expand Down
20 changes: 20 additions & 0 deletions include/vast/Dialect/Core/Interfaces/DeclStorageInterface.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) 2024, Trail of Bits, Inc.

Check notice on line 1 in include/vast/Dialect/Core/Interfaces/DeclStorageInterface.hpp

View workflow job for this annotation

GitHub Actions / cpp-linter (18, 22.04)

Run clang-format on include/vast/Dialect/Core/Interfaces/DeclStorageInterface.hpp

File include/vast/Dialect/Core/Interfaces/DeclStorageInterface.hpp does not conform to Custom style guidelines. (lines 8)

#pragma once

#include "vast/Util/Warnings.hpp"

VAST_RELAX_WARNINGS
#include <mlir/Interfaces/FunctionInterfaces.h>
#include <mlir/IR/BuiltinOps.h>
#include <mlir/IR/BuiltinTypes.h>
#include <mlir/IR/Dialect.h>
#include <mlir/IR/OperationSupport.h>
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"
124 changes: 124 additions & 0 deletions include/vast/Dialect/Core/Interfaces/DeclStorageInterface.td
Original file line number Diff line number Diff line change
@@ -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
3 changes: 3 additions & 0 deletions include/vast/Dialect/Core/Linkage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

VAST_RELAX_WARNINGS
#include <clang/AST/GlobalDecl.h>
#include <mlir/Dialect/LLVMIR/LLVMAttrs.h>
VAST_UNRELAX_WARNINGS

#include "vast/Dialect/HighLevel/HighLevelAttributes.hpp"
Expand All @@ -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
19 changes: 19 additions & 0 deletions include/vast/Dialect/Core/LinkageHelper.td
Original file line number Diff line number Diff line change
@@ -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
31 changes: 31 additions & 0 deletions include/vast/Dialect/Core/StorageInfo.td
Original file line number Diff line number Diff line change
@@ -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
Loading