Skip to content

Commit

Permalink
XXX: Add linkage to vars.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jezurko committed Sep 24, 2024
1 parent 6c4f4f1 commit 6080354
Show file tree
Hide file tree
Showing 15 changed files with 123 additions and 70 deletions.
44 changes: 0 additions & 44 deletions include/vast/Dialect/Core/CoreAttributes.td
Original file line number Diff line number Diff line change
Expand Up @@ -219,23 +219,6 @@ def Core_StorageDuration
Core_SD_Dynamic
] >;

class Core_StorageDurationImpl
{
code storageDurationImpl = [{
bool hasLocalStorage();

bool isLocalVarDecl();

bool isStaticLocal();

bool hasExternalStorage();

bool hasGlobalStorage();

StorageDuration getStorageDuration();
}];
}

// declaration context kinds
class Core_DeclContextAttr< string name, int val > : I64EnumAttrCase< name, val > {}

Expand Down Expand Up @@ -266,31 +249,4 @@ def Core_DeclContextKind
Core_DC_Namespace
] >;

class Core_DeclContextImpl
{
code declContextImpl = [{
DeclContextKind getDeclContextKind();

bool isStaticDataMember();

bool isInFileContext();

bool isInFunctionOrMethodContext();

bool isInRecordContext();

bool isFileVarDecl();
}];
}

class Core_StorageSpecifiers :
Core_StorageDurationImpl,
Core_DeclContextImpl
{
code storageSpecifiersImpl =
storageDurationImpl #
declContextImpl;
}


#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
5 changes: 4 additions & 1 deletion include/vast/Dialect/Core/Interfaces/DeclStorageInterface.td
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ def Core_DeclStorageInterface : Core_OpInterface< "DeclStorageInterface" > {
InterfaceMethod<"",
"::vast::core::DeclContextKind", "getDeclContextKind", (ins), [{}],
/*defaultImplementation=*/[{
auto st = core::get_effective_symbol_table_for< core::var_symbol >(this->getOperation())->get_defining_operation();
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 >())
Expand Down
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
7 changes: 5 additions & 2 deletions include/vast/Dialect/HighLevel/HighLevelVar.td
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
include "vast/Dialect/Core/CoreTraits.td"
include "vast/Dialect/Core/StorageInfo.td"
include "vast/Dialect/Core/Interfaces/DeclStorageInterface.td"
include "vast/Dialect/Core/LinkageHelper.td"

// Variable Operation
def HighLevel_VarDeclOp
Expand All @@ -22,7 +23,8 @@ def HighLevel_VarDeclOp
SymbolNameAttr:$sym_name,
TypeAttr:$type,
Core_StorageClass:$storageClass,
Core_ThreadStorage:$threadStorageClass
Core_ThreadStorage:$threadStorageClass,
OptionalAttr<Core_GlobalLinkageKind>:$linkage
);

let regions = (region
Expand All @@ -36,13 +38,14 @@ def HighLevel_VarDeclOp
"llvm::StringRef":$sym_name,
"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^)?
Expand Down
11 changes: 11 additions & 0 deletions lib/vast/CodeGen/DefaultDeclVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,13 +216,24 @@ 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))
.bind(visit_as_lvalue_type(self, mctx, decl->getType()))
.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))
Expand Down
29 changes: 22 additions & 7 deletions lib/vast/Conversion/ToLLVM/IRsToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -356,13 +357,25 @@ namespace vast::conv::irstollvm
auto target_type = this->convert(t.getElementType());

// 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();
}
}

auto gop = rewriter.create< mlir::LLVM::GlobalOp >(
op.getLoc(),
target_type,
// TODO(conv:irstollvm): Constant.
true,
LLVM::Linkage::Internal,
op.getSymbolName(), mlir::Attribute());
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
Expand Down Expand Up @@ -437,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
);

Expand Down
8 changes: 6 additions & 2 deletions lib/vast/Conversion/ToMem/EvictStaticLocals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,16 @@ namespace vast::conv {

auto new_decl = rewriter.create< hl::VarDeclOp >(
op.getLoc(),
(parent_fn.getName() + "." + op.getSymName()).str(),
op.getType(),
(parent_fn.getName() + "." + op.getSymName()).str(),
op.getStorageClass(),
op.getThreadStorageClass()
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());

Expand Down
27 changes: 27 additions & 0 deletions lib/vast/Dialect/Core/Linkage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,4 +276,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
4 changes: 4 additions & 0 deletions lib/vast/Dialect/HighLevel/HighLevelOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ namespace vast::hl
llvm::StringRef name,
core::StorageClass storage_class,
core::TSClass thread_storage_class,
std::optional< core::GlobalLinkageKind > linkage,
maybe_builder_callback_ref init,
maybe_builder_callback_ref alloc
) {
Expand All @@ -352,6 +353,9 @@ namespace vast::hl
st.addAttribute("type", mlir::TypeAttr::get(type));
st.addAttribute("storageClass", core::StorageClassAttr::get(ctx, storage_class));
st.addAttribute("threadStorageClass", core::TSClassAttr::get(ctx, thread_storage_class));
if (linkage) {
st.addAttribute("liinkage", core::GlobalLinkageKindAttr::get(ctx, linkage.value()));
}
InsertionGuard guard(bld);

build_region(bld, st, init);
Expand Down
1 change: 1 addition & 0 deletions test/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion test/vast/Conversion/cmake-platform-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
Expand Down
18 changes: 18 additions & 0 deletions test/vast/Conversion/static-var-a.c
Original file line number Diff line number Diff line change
@@ -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 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++;
}
2 changes: 1 addition & 1 deletion test/vast/Conversion/subscript-b.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// 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 internal @arr1() {addr_space = 0 : i32} : !llvm.array<3 x i32> {

int arr1[] = { 0, 2, 4 };

Expand Down

0 comments on commit 6080354

Please sign in to comment.