MaskRay created this revision. MaskRay added reviewers: compnerd, craig.topper, rsmith. Herald added subscribers: ormris, StephenFan, frasercrmck, dexonsmith, dang, luismarques, apazos, sameer.abuasal, pengfei, s.egerton, Jim, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, jrtc27, niosHD, sabuasal, simoncook, johnrusso, rbar, asb, hiraditya. MaskRay requested review of this revision. Herald added projects: clang, LLVM. Herald added subscribers: llvm-commits, cfe-commits.
GCC supports multiple forms of -falign-loops=. This patch implements the simplest but the most useful form where N is a power of 2. A lib/CodeGen/CommandFlags.cpp option "-align-loops=" is added. It can replace -x86-experimental-pref-loop-alignment=. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D106701 Files: clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Basic/DiagnosticDriverKinds.td clang/include/clang/Basic/LangOptions.def clang/include/clang/Driver/Options.td clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/test/Driver/falign-loops.c llvm/include/llvm/CodeGen/CommandFlags.h llvm/include/llvm/CodeGen/TargetLowering.h llvm/include/llvm/Target/TargetOptions.h llvm/lib/CodeGen/CommandFlags.cpp llvm/lib/CodeGen/TargetLoweringBase.cpp llvm/test/CodeGen/RISCV/loop-alignment.ll llvm/test/CodeGen/X86/innermost-loop-alignment.ll
Index: llvm/test/CodeGen/X86/innermost-loop-alignment.ll =================================================================== --- llvm/test/CodeGen/X86/innermost-loop-alignment.ll +++ llvm/test/CodeGen/X86/innermost-loop-alignment.ll @@ -1,7 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=i686-pc-linux-gnu | FileCheck %s -check-prefix=DEFAULT ; RUN: llc < %s -mtriple=i686-pc-linux-gnu -x86-experimental-pref-innermost-loop-alignment=5 | FileCheck %s -check-prefix=ALIGN32 -; RUN: llc < %s -mtriple=i686-pc-linux-gnu -x86-experimental-pref-loop-alignment=5 -x86-experimental-pref-innermost-loop-alignment=6 | FileCheck %s -check-prefix=ALIGN64 +; RUN: llc < %s -mtriple=i686-pc-linux-gnu -align-loops=32 -x86-experimental-pref-innermost-loop-alignment=6 | FileCheck %s -check-prefix=ALIGN64 declare void @foo() Index: llvm/test/CodeGen/RISCV/loop-alignment.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/RISCV/loop-alignment.ll @@ -0,0 +1,45 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=riscv64 | FileCheck %s +; RUN: llc < %s -mtriple=riscv64 -align-loops=16 | FileCheck %s -check-prefix=ALIGN_16 +; RUN: llc < %s -mtriple=riscv64 -align-loops=32 | FileCheck %s -check-prefix=ALIGN_32 + +declare void @foo() + +define void @test(i32 %n, i32 %m) nounwind { +; CHECK-LABEL: test: +; CHECK-NOT: .p2align +; CHECK: ret + +; ALIGN_16-LABEL: test: +; ALIGN_16: .p2align 4 +; ALIGN_16-NEXT: .LBB0_1: # %outer +; ALIGN_16: .p2align 4 +; ALIGN_16-NEXT: .LBB0_2: # %inner + +; ALIGN_32-LABEL: test: +; ALIGN_32: .p2align 5 +; ALIGN_32-NEXT: .LBB0_1: # %outer +; ALIGN_32: .p2align 5 +; ALIGN_32-NEXT: .LBB0_2: # %inner +entry: + br label %outer + +outer: + %outer.iv = phi i32 [0, %entry], [%outer.iv.next, %outer_bb] + br label %inner + +inner: + %inner.iv = phi i32 [0, %outer], [%inner.iv.next, %inner] + call void @foo() + %inner.iv.next = add i32 %inner.iv, 1 + %inner.cond = icmp ne i32 %inner.iv.next, %m + br i1 %inner.cond, label %inner, label %outer_bb + +outer_bb: + %outer.iv.next = add i32 %outer.iv, 1 + %outer.cond = icmp ne i32 %outer.iv.next, %n + br i1 %outer.cond, label %outer, label %exit + +exit: + ret void +} Index: llvm/lib/CodeGen/TargetLoweringBase.cpp =================================================================== --- llvm/lib/CodeGen/TargetLoweringBase.cpp +++ llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -52,6 +52,7 @@ #include "llvm/Support/MachineValueType.h" #include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" #include "llvm/Transforms/Utils/SizeOpts.h" #include <algorithm> #include <cassert> @@ -2020,6 +2021,12 @@ return getTargetMachine().isPositionIndependent(); } +Align TargetLoweringBase::getPrefLoopAlignment(MachineLoop *ML) const { + if (TM.Options.LoopAlignment) + return Align(TM.Options.LoopAlignment); + return PrefLoopAlignment; +} + //===----------------------------------------------------------------------===// // Reciprocal Estimates //===----------------------------------------------------------------------===// Index: llvm/lib/CodeGen/CommandFlags.cpp =================================================================== --- llvm/lib/CodeGen/CommandFlags.cpp +++ llvm/lib/CodeGen/CommandFlags.cpp @@ -94,6 +94,7 @@ CGOPT(bool, ForceDwarfFrameSection) CGOPT(bool, XRayOmitFunctionIndex) CGOPT(bool, DebugStrictDwarf) +CGOPT(unsigned, AlignLoops) codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() { #define CGBINDOPT(NAME) \ @@ -452,6 +453,10 @@ "strict-dwarf", cl::desc("use strict dwarf"), cl::init(false)); CGBINDOPT(DebugStrictDwarf); + static cl::opt<unsigned> AlignLoops("align-loops", + cl::desc("Default alignment for loops")); + CGBINDOPT(AlignLoops); + #undef CGBINDOPT mc::RegisterMCTargetOptionsFlags(); @@ -527,6 +532,7 @@ Options.ForceDwarfFrameSection = getForceDwarfFrameSection(); Options.XRayOmitFunctionIndex = getXRayOmitFunctionIndex(); Options.DebugStrictDwarf = getDebugStrictDwarf(); + Options.LoopAlignment = getAlignLoops(); Options.MCOptions = mc::InitMCTargetOptionsFromFlags(); Index: llvm/include/llvm/Target/TargetOptions.h =================================================================== --- llvm/include/llvm/Target/TargetOptions.h +++ llvm/include/llvm/Target/TargetOptions.h @@ -328,6 +328,9 @@ /// passed on the command line. std::string StackUsageOutput; + /// If greater than 0, override TargetLoweringBase::PrefLoopAlignment. + unsigned LoopAlignment = 0; + /// FloatABIType - This setting is set by -float-abi=xxx option is specfied /// on the command line. This setting may either be Default, Soft, or Hard. /// Default selects the target's default behavior. Soft selects the ABI for Index: llvm/include/llvm/CodeGen/TargetLowering.h =================================================================== --- llvm/include/llvm/CodeGen/TargetLowering.h +++ llvm/include/llvm/CodeGen/TargetLowering.h @@ -1763,9 +1763,7 @@ Align getPrefFunctionAlignment() const { return PrefFunctionAlignment; } /// Return the preferred loop alignment. - virtual Align getPrefLoopAlignment(MachineLoop *ML = nullptr) const { - return PrefLoopAlignment; - } + virtual Align getPrefLoopAlignment(MachineLoop *ML = nullptr) const; /// Should loops be aligned even when the function is marked OptSize (but not /// MinSize). Index: llvm/include/llvm/CodeGen/CommandFlags.h =================================================================== --- llvm/include/llvm/CodeGen/CommandFlags.h +++ llvm/include/llvm/CodeGen/CommandFlags.h @@ -138,6 +138,8 @@ bool getDebugStrictDwarf(); +unsigned getAlignLoops(); + /// Create this object with static storage to register codegen-related command /// line options. struct RegisterCodeGenFlags { Index: clang/test/Driver/falign-loops.c =================================================================== --- /dev/null +++ clang/test/Driver/falign-loops.c @@ -0,0 +1,16 @@ +/// Treat -falign-loops=0 as not specifying the option. +// RUN: %clang -### -falign-loops=0 %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO +// RUN: %clang -### -falign-loops=1 %s 2>&1 | FileCheck %s --check-prefix=CHECK-1 +// RUN: %clang -### -falign-loops=4 %s 2>&1 | FileCheck %s --check-prefix=CHECK-4 +// RUN: %clang -### -falign-loops=5 %s 2>&1 | FileCheck %s --check-prefix=CHECK-5 +// RUN: %clang -### -falign-loops=8 %s 2>&1 | FileCheck %s --check-prefix=CHECK-8 +// RUN: %clang -### -falign-loops=65537 %s 2>&1 | FileCheck %s --check-prefix=CHECK-65537 +// RUN: %clang -### -falign-loops=a %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERR-A + +// CHECK-NO-NOT: "-falign-loops= +// CHECK-1: "-falign-loops=1" +// CHECK-4: "-falign-loops=4" +// CHECK-5: error: alignment is not a power of 2 in '-falign-loops=5' +// CHECK-8: "-falign-loops=8" +// CHECK-65537: error: invalid integral value '65537' in '-falign-loops=65537' +// CHECK-ERR-A: error: invalid integral value 'a' in '-falign-loops=a' Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -4720,6 +4720,23 @@ CmdArgs.push_back(Args.MakeArgString(std::to_string(FunctionAlignment))); } + // We support -falign-loops=N where N is a power of 2. GCC supports more + // forms. + if (const Arg *A = Args.getLastArg(options::OPT_falign_loops_EQ)) { + unsigned Value = 0; + if (StringRef(A->getValue()).getAsInteger(10, Value) || Value > 65536) + TC.getDriver().Diag(diag::err_drv_invalid_int_value) + << A->getAsString(Args) << A->getValue(); + else if (Value & Value - 1) + TC.getDriver().Diag(diag::err_drv_alignment_not_power_of_two) + << A->getAsString(Args) << A->getValue(); + // Treat =0 as not specifying the option (use the target preference). In GCC + // =0 is the same as =1. + if (Value) + CmdArgs.push_back(Args.MakeArgString("-falign-loops=" + + Twine(std::min(Value, 65536u)))); + } + llvm::Reloc::Model RelocationModel; unsigned PICLevel; bool IsPIE; Index: clang/lib/CodeGen/BackendUtil.cpp =================================================================== --- clang/lib/CodeGen/BackendUtil.cpp +++ clang/lib/CodeGen/BackendUtil.cpp @@ -580,6 +580,7 @@ Options.ValueTrackingVariableLocations = CodeGenOpts.ValueTrackingVariableLocations; Options.XRayOmitFunctionIndex = CodeGenOpts.XRayOmitFunctionIndex; + Options.LoopAlignment = CodeGenOpts.LoopAlignment; Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile; Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll; Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -1064,6 +1064,8 @@ PosFlag<SetTrue>>; def falign_functions : Flag<["-"], "falign-functions">, Group<f_Group>; def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<f_Group>; +def falign_loops_EQ : Joined<["-"], "falign-loops=">, Group<f_Group>, Flags<[CC1Option]>, + MarshallingInfoInt<CodeGenOpts<"LoopAlignment">>; def fno_align_functions: Flag<["-"], "fno-align-functions">, Group<f_Group>; defm allow_editor_placeholders : BoolFOption<"allow-editor-placeholders", LangOpts<"AllowEditorPlaceholders">, DefaultFalse, @@ -4293,7 +4295,6 @@ defm align_labels : BooleanFFlag<"align-labels">, Group<clang_ignored_gcc_optimization_f_Group>; def falign_labels_EQ : Joined<["-"], "falign-labels=">, Group<clang_ignored_gcc_optimization_f_Group>; defm align_loops : BooleanFFlag<"align-loops">, Group<clang_ignored_gcc_optimization_f_Group>; -def falign_loops_EQ : Joined<["-"], "falign-loops=">, Group<clang_ignored_gcc_optimization_f_Group>; defm align_jumps : BooleanFFlag<"align-jumps">, Group<clang_ignored_gcc_optimization_f_Group>; def falign_jumps_EQ : Joined<["-"], "falign-jumps=">, Group<clang_ignored_gcc_optimization_f_Group>; Index: clang/include/clang/Basic/LangOptions.def =================================================================== --- clang/include/clang/Basic/LangOptions.def +++ clang/include/clang/Basic/LangOptions.def @@ -396,6 +396,7 @@ "with") COMPATIBLE_VALUE_LANGOPT(FunctionAlignment, 5, 0, "Default alignment for functions") +COMPATIBLE_VALUE_LANGOPT(LoopAlignment, 32, 0, "Default alignment for loops") LANGOPT(FixedPoint, 1, 0, "fixed point types") LANGOPT(PaddingOnUnsignedFixedPoint, 1, 0, Index: clang/include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticDriverKinds.td +++ clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -218,6 +218,7 @@ def err_drv_invalid_int_value : Error<"invalid integral value '%1' in '%0'">; def err_drv_invalid_value_with_suggestion : Error< "invalid value '%1' in '%0', expected one of: %2">; +def err_drv_alignment_not_power_of_two : Error<"alignment is not a power of 2 in '%0'">; def err_drv_invalid_remap_file : Error< "invalid option '%0' not of the form <from-file>;<to-file>">; def err_drv_invalid_gcc_output_type : Error< Index: clang/include/clang/Basic/CodeGenOptions.def =================================================================== --- clang/include/clang/Basic/CodeGenOptions.def +++ clang/include/clang/Basic/CodeGenOptions.def @@ -293,6 +293,8 @@ ///< realignment. CODEGENOPT(UseInitArray , 1, 0) ///< Control whether to use .init_array or ///< .ctors. +VALUE_CODEGENOPT(LoopAlignment , 32, 0) ///< Overrides default loop + ///< alignment, if not 0. VALUE_CODEGENOPT(StackAlignment , 32, 0) ///< Overrides default stack ///< alignment, if not 0. VALUE_CODEGENOPT(StackProbeSize , 32, 4096) ///< Overrides default stack
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits