edward-jones updated this revision to Diff 374609.
edward-jones added a comment.
Herald added a subscriber: achieveartificialintelligence.
Changes here:
- Merged the separate attributes overlaycall and overlaydata into a single
overlay attribute (though I may need to undo this to match the high level
document)
- Fixed to use the correct type of attribute and handle it in a less sloppy
way
- Errors/warnings messages are hopefully more descriptive now
- Renamed option to -moverlay to match the high level document
- It's no longer an error to use the attribute without -moverlay, you'll just
get "attribute ignored" warnings
- Updated tests
Still to do:
- Writing more tests
- Warn the user to turn on -moverlay as a fix for "attribute ignored" warnings
- Rebase
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D109372/new/
https://reviews.llvm.org/D109372
Files:
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Basic/DiagnosticDriverKinds.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Basic/LangOptions.def
clang/include/clang/Driver/Options.td
clang/lib/CodeGen/CGCall.cpp
clang/lib/CodeGen/CodeGenModule.cpp
clang/lib/Driver/ToolChains/Arch/RISCV.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/CodeGen/riscv-overlay.c
clang/test/Driver/riscv-overlay.c
clang/test/Sema/riscv-overlay-attr.c
clang/test/Sema/riscv-overlay-namespace.cpp
Index: clang/test/Sema/riscv-overlay-namespace.cpp
===================================================================
--- /dev/null
+++ clang/test/Sema/riscv-overlay-namespace.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -triple riscv32-unknown-elf -verify -fsyntax-only -moverlay
+// RUN: %clang_cc1 %s -triple riscv64-unknown-elf -verify -fsyntax-only -moverlay
+
+namespace {
+class foo {
+public:
+ static int X() __attribute__((overlay)) { return 0; } // expected-error {{functions marked with 'overlay' attribute must have external linkage}}
+};
+} // end of anonymous namespace
+
+namespace X {
+class bar {
+public:
+ static int X() __attribute__((overlay)) { return 1; }
+};
+} // end of namespace X
+
+extern "C" {
+int main(void) { return foo::X() + X::bar::X(); }
+}
Index: clang/test/Sema/riscv-overlay-attr.c
===================================================================
--- /dev/null
+++ clang/test/Sema/riscv-overlay-attr.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple riscv32 -moverlay -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple riscv64 -moverlay -fsyntax-only -verify %s
+
+int notAFunction __attribute__((overlay));
+// expected-warning@-1 {{'overlay' attribute only applies to functions and global constants}}
+
+void incompatForwardDecl(int x);
+void __attribute__((overlay)) incompatForwardDecl(int x) {}
+// expected-error@-1 {{redeclaration of 'incompatForwardDecl' must not have the 'overlay' attribute}}
+// expected-note@-3 {{previous definition is here}}
+
+static void staticcall() __attribute__((overlay)) {}
+// expected-error@-1 {{functions marked with 'overlay' attribute must have external linkage}}
+
+static void __attribute__((overlay)) staticcall2() {}
+// expected-error@-1 {{functions marked with 'overlay' attribute must have external linkage}}
Index: clang/test/Driver/riscv-overlay.c
===================================================================
--- /dev/null
+++ clang/test/Driver/riscv-overlay.c
@@ -0,0 +1,5 @@
+// Check that ComRV Driver Arguments
+
+// RUN: not %clang -target riscv32 -moverlay %s -o %t.o -mabi=ilp32f 2>&1 \
+// RUN: | FileCheck -check-prefix=INVALID-ABI %s
+// INVALID-ABI: invalid ABI 'ilp32f' when using '-moverlay'
Index: clang/test/CodeGen/riscv-overlay.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/riscv-overlay.c
@@ -0,0 +1,11 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes
+// RUN: %clang_cc1 -triple riscv32 -moverlay -emit-llvm %s -o - \
+// RUN: | FileCheck %s
+
+// CHECK-LABEL: @test_overlay_func(
+// CHECK-SAME: #0
+// CHECK: attributes #0 = {
+// CHECK-SAME: "overlay"
+int __attribute__((overlay)) test_overlay_func(void) {
+ return 5;
+}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -2039,6 +2039,29 @@
D->addAttr(::new (S.Context) CmseNSEntryAttr(S.Context, AL));
}
+static void handleRISCVOverlayAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ if (!S.getLangOpts().Overlay) {
+ S.Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored) << AL;
+ return;
+ }
+
+ if (isFunctionOrMethod(D)) {
+ const auto *FD = cast<FunctionDecl>(D);
+ if (!FD->isExternallyVisible()) {
+ S.Diag(AL.getLoc(), diag::err_overlay_func_external_linkage);
+ AL.setInvalid();
+ return;
+ }
+
+ // 'overlay' on a function implies 'noinline'
+ Attr *A = ::new (S.Context) NoInlineAttr(S.Context, AL);
+ A->setImplicit(true);
+ D->addAttr(A);
+ }
+
+ handleSimpleAttribute<RISCVOverlayAttr>(S, D, AL);
+}
+
static void handleNakedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
if (AL.isDeclspecAttribute()) {
const auto &Triple = S.getASTContext().getTargetInfo().getTriple();
@@ -8264,6 +8287,9 @@
case ParsedAttr::AT_CmseNSEntry:
handleCmseNSEntryAttr(S, D, AL);
break;
+ case ParsedAttr::AT_RISCVOverlay:
+ handleRISCVOverlayAttr(S, D, AL);
+ break;
case ParsedAttr::AT_StdCall:
case ParsedAttr::AT_CDecl:
case ParsedAttr::AT_FastCall:
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -3358,6 +3358,15 @@
}
}
+ bool NewIsOverlayCall = New->hasAttr<RISCVOverlayAttr>();
+ bool OldIsOverlayCall = Old->hasAttr<RISCVOverlayAttr>();
+ if (NewIsOverlayCall != OldIsOverlayCall) {
+ Diag(New->getLocation(), diag::err_overlay_mismatch)
+ << New << OldIsOverlayCall;
+ notePreviousDefinition(Old, New->getLocation());
+ return true;
+ }
+
if (const auto *ILA = New->getAttr<InternalLinkageAttr>())
if (!Old->hasAttr<InternalLinkageAttr>()) {
Diag(New->getLocation(), diag::err_attribute_missing_on_first_decl)
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -2095,6 +2095,15 @@
CmdArgs.push_back("-tune-cpu");
CmdArgs.push_back(Args.MakeArgString(TuneCPU));
}
+
+ // If comrv mode is requested, pass on this flag, and produce an error if an
+ // invalid ABI has been requested
+ if (Args.getLastArg(options::OPT_moverlay)) {
+ CmdArgs.push_back("-moverlay");
+ if (ABIName != "ilp32")
+ getToolChain().getDriver().Diag(diag::err_drv_invalid_riscv_abi_moverlay)
+ << ABIName;
+ }
}
void Clang::AddSparcTargetArgs(const ArgList &Args,
Index: clang/lib/Driver/ToolChains/Arch/RISCV.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -492,6 +492,14 @@
if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
getRISCFeaturesFromMcpu(D, Triple, Args, A, A->getValue(), Features);
+ // Extra register reservations required to handle -moverlay
+ if (Args.hasArg(options::OPT_moverlay)) {
+ Features.push_back("+reserve-x28"); // Overlay Stack Register
+ Features.push_back("+reserve-x29"); // Overlay Stack Frames Pool Register
+ Features.push_back("+reserve-x30"); // Overlay Address Token Reg
+ Features.push_back("+reserve-x31"); // Overlay Entry Point Address Register
+ }
+
// Handle features corresponding to "-ffixed-X" options
if (Args.hasArg(options::OPT_ffixed_x1))
Features.push_back("+reserve-x1");
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -1880,6 +1880,10 @@
if (LangOpts.FunctionAlignment)
F->setAlignment(llvm::Align(1ull << LangOpts.FunctionAlignment));
+ // Overlay functions must have a minimum 4-byte alignment.
+ if (F->getAlignment() < 4 && D->hasAttr<RISCVOverlayAttr>())
+ F->setAlignment(llvm::Align(4));
+
// Some C++ ABIs require 2-byte alignment for member functions, in order to
// reserve a bit for differentiating between virtual and non-virtual member
// functions. If the current target's C++ ABI requires this and this is a
@@ -4525,6 +4529,9 @@
if (CGDebugInfo *DI = getModuleDebugInfo())
if (getCodeGenOpts().hasReducedDebugInfo())
DI->EmitGlobalVariable(GV, D);
+
+ if (D->hasAttr<RISCVOverlayAttr>())
+ GV->addAttribute("overlay");
}
void CodeGenModule::EmitExternalVarDeclaration(const VarDecl *D) {
Index: clang/lib/CodeGen/CGCall.cpp
===================================================================
--- clang/lib/CodeGen/CGCall.cpp
+++ clang/lib/CodeGen/CGCall.cpp
@@ -2199,8 +2199,12 @@
// Collect non-call-site function IR attributes from declaration-specific
// information.
if (!AttrOnCallSite) {
- if (TargetDecl && TargetDecl->hasAttr<CmseNSEntryAttr>())
- FuncAttrs.addAttribute("cmse_nonsecure_entry");
+ if (TargetDecl) {
+ if (TargetDecl->hasAttr<RISCVOverlayAttr>())
+ FuncAttrs.addAttribute("overlay");
+ if (TargetDecl->hasAttr<CmseNSEntryAttr>())
+ FuncAttrs.addAttribute("cmse_nonsecure_entry");
+ }
// Whether tail calls are enabled.
auto shouldDisableTailCalls = [&] {
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -3229,6 +3229,10 @@
HelpText<"Equivalent to -mcmodel=medium, compatible with RISC-V gcc.">;
def menable_experimental_extensions : Flag<["-"], "menable-experimental-extensions">, Group<m_Group>,
HelpText<"Enable use of experimental RISC-V extensions.">;
+def moverlay : Flag<["-"], "moverlay">,
+ Group<m_Group>, Flags<[CC1Option]>,
+ HelpText<"Enable RISC-V overlay manager support">,
+ MarshallingInfoFlag<LangOpts<"Overlay">>;
def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_arm_Features_Group>,
HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">;
Index: clang/include/clang/Basic/LangOptions.def
===================================================================
--- clang/include/clang/Basic/LangOptions.def
+++ clang/include/clang/Basic/LangOptions.def
@@ -428,6 +428,10 @@
"Controls how scalar integer arguments are extended in calls "
"to unprototyped and varargs functions")
+LANGOPT(Overlay, 1, 0,
+ "Enable support for use of an overlay system for calls and data "
+ "accesses")
+
#undef LANGOPT
#undef COMPATIBLE_LANGOPT
#undef BENIGN_LANGOPT
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -309,6 +309,10 @@
"repeated RISC-V 'interrupt' attribute">, InGroup<IgnoredAttributes>;
def note_riscv_repeated_interrupt_attribute : Note<
"repeated RISC-V 'interrupt' attribute is here">;
+def err_overlay_func_external_linkage : Error<
+ "functions marked with 'overlay' attribute must have external linkage">;
+def err_overlay_mismatch : Error<
+ "redeclaration of %0 must %select{not |}1have the 'overlay' attribute">;
def warn_unused_parameter : Warning<"unused parameter %0">,
InGroup<UnusedParameter>, DefaultIgnore;
def warn_unused_but_set_parameter : Warning<"parameter %0 set but not used">,
Index: clang/include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -32,6 +32,8 @@
def warn_drv_invalid_arch_name_with_suggestion : Warning<
"ignoring invalid /arch: argument '%0'; for %select{64|32}1-bit expected one of %2">,
InGroup<UnusedCommandLineArgument>;
+def err_drv_invalid_riscv_abi_moverlay : Error<
+ "invalid ABI '%0' when using '-moverlay'">;
def warn_drv_avr_mcu_not_specified : Warning<
"no target microcontroller specified on command line, cannot "
"link standard libraries, please pass -mmcu=<mcu name>">,
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -2142,6 +2142,16 @@
}];
}
+def RISCVOverlayDocs : Documentation {
+ let Category = DocCatVariable;
+ let Heading = "overlay (RISCV)";
+ let Content = [{
+``__attribute__((overlay))`` indicates that a function or data exists in an
+overlay. Calls to functions, and accessing data will generate indirect accesses
+through the overlay engine.
+ }];
+}
+
def AVRInterruptDocs : Documentation {
let Category = DocCatFunction;
let Heading = "interrupt (AVR)";
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -118,6 +118,11 @@
def GlobalVar : SubsetSubject<Var,
[{S->hasGlobalStorage()}], "global variables">;
+def GlobalConst : SubsetSubject<Var,
+ [{S->hasGlobalStorage() &&
+ S->getType().isConstQualified()}],
+ "global constants">;
+
def InlineFunction : SubsetSubject<Function,
[{S->isInlineSpecified()}], "inline functions">;
@@ -1782,6 +1787,12 @@
let Documentation = [RISCVInterruptDocs];
}
+def RISCVOverlay : InheritableAttr, TargetSpecificAttr<TargetRISCV> {
+ let Spellings = [Clang<"overlay">];
+ let Subjects = SubjectList<[Function, GlobalConst]>;
+ let Documentation = [RISCVOverlayDocs];
+}
+
// This is not a TargetSpecificAttr so that is silently accepted and
// ignored on other targets as encouraged by the OpenCL spec.
//
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits