summaryrefslogtreecommitdiff
path: root/include/llvm/CodeGen
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:12 +0000
commite6d1592492a3a379186bfb02bd0f4eda0669c0d5 (patch)
tree599ab169a01f1c86eda9adc774edaedde2f2db5b /include/llvm/CodeGen
parent1a56a5ead7a2e84bee8240f5f6b033b5f1707154 (diff)
Notes
Diffstat (limited to 'include/llvm/CodeGen')
-rw-r--r--include/llvm/CodeGen/AccelTable.h31
-rw-r--r--include/llvm/CodeGen/Analysis.h27
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h61
-rw-r--r--include/llvm/CodeGen/AsmPrinterHandler.h7
-rw-r--r--include/llvm/CodeGen/AtomicExpandUtils.h7
-rw-r--r--include/llvm/CodeGen/BasicTTIImpl.h250
-rw-r--r--include/llvm/CodeGen/BuiltinGCs.h7
-rw-r--r--include/llvm/CodeGen/CSEConfigBase.h28
-rw-r--r--include/llvm/CodeGen/CalcSpillWeights.h7
-rw-r--r--include/llvm/CodeGen/CallingConvLower.h11
-rw-r--r--include/llvm/CodeGen/CommandFlags.inc13
-rw-r--r--include/llvm/CodeGen/CostTable.h7
-rw-r--r--include/llvm/CodeGen/DAGCombine.h7
-rw-r--r--include/llvm/CodeGen/DFAPacketizer.h7
-rw-r--r--include/llvm/CodeGen/DIE.h59
-rw-r--r--include/llvm/CodeGen/DIEValue.def8
-rw-r--r--include/llvm/CodeGen/DbgEntityHistoryCalculator.h89
-rw-r--r--include/llvm/CodeGen/DebugHandlerBase.h9
-rw-r--r--include/llvm/CodeGen/DwarfStringPoolEntry.h7
-rw-r--r--include/llvm/CodeGen/EdgeBundles.h7
-rw-r--r--include/llvm/CodeGen/ExecutionDomainFix.h7
-rw-r--r--include/llvm/CodeGen/ExpandReductions.h7
-rw-r--r--include/llvm/CodeGen/FastISel.h9
-rw-r--r--include/llvm/CodeGen/FaultMaps.h7
-rw-r--r--include/llvm/CodeGen/FunctionLoweringInfo.h65
-rw-r--r--include/llvm/CodeGen/GCMetadata.h7
-rw-r--r--include/llvm/CodeGen/GCMetadataPrinter.h7
-rw-r--r--include/llvm/CodeGen/GCStrategy.h7
-rw-r--r--include/llvm/CodeGen/GlobalISel/CSEInfo.h41
-rw-r--r--include/llvm/CodeGen/GlobalISel/CSEMIRBuilder.h7
-rw-r--r--include/llvm/CodeGen/GlobalISel/CallLowering.h137
-rw-r--r--include/llvm/CodeGen/GlobalISel/Combiner.h9
-rw-r--r--include/llvm/CodeGen/GlobalISel/CombinerHelper.h27
-rw-r--r--include/llvm/CodeGen/GlobalISel/CombinerInfo.h7
-rw-r--r--include/llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.h7
-rw-r--r--include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h18
-rw-r--r--include/llvm/CodeGen/GlobalISel/GISelWorkList.h50
-rw-r--r--include/llvm/CodeGen/GlobalISel/IRTranslator.h121
-rw-r--r--include/llvm/CodeGen/GlobalISel/InstructionSelect.h7
-rw-r--r--include/llvm/CodeGen/GlobalISel/InstructionSelector.h17
-rw-r--r--include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h60
-rw-r--r--include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h276
-rw-r--r--include/llvm/CodeGen/GlobalISel/Legalizer.h14
-rw-r--r--include/llvm/CodeGen/GlobalISel/LegalizerHelper.h120
-rw-r--r--include/llvm/CodeGen/GlobalISel/LegalizerInfo.h211
-rw-r--r--include/llvm/CodeGen/GlobalISel/Localizer.h22
-rw-r--r--include/llvm/CodeGen/GlobalISel/MIPatternMatch.h14
-rw-r--r--include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h361
-rw-r--r--include/llvm/CodeGen/GlobalISel/RegBankSelect.h16
-rw-r--r--include/llvm/CodeGen/GlobalISel/RegisterBank.h7
-rw-r--r--include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h53
-rw-r--r--include/llvm/CodeGen/GlobalISel/Types.h7
-rw-r--r--include/llvm/CodeGen/GlobalISel/Utils.h74
-rw-r--r--include/llvm/CodeGen/ISDOpcodes.h54
-rw-r--r--include/llvm/CodeGen/IntrinsicLowering.h11
-rw-r--r--include/llvm/CodeGen/LatencyPriorityQueue.h7
-rw-r--r--include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h7
-rw-r--r--include/llvm/CodeGen/LexicalScopes.h7
-rw-r--r--include/llvm/CodeGen/LinkAllAsmWriterComponents.h7
-rw-r--r--include/llvm/CodeGen/LinkAllCodegenComponents.h7
-rw-r--r--include/llvm/CodeGen/LiveInterval.h54
-rw-r--r--include/llvm/CodeGen/LiveIntervalUnion.h7
-rw-r--r--include/llvm/CodeGen/LiveIntervals.h16
-rw-r--r--include/llvm/CodeGen/LivePhysRegs.h7
-rw-r--r--include/llvm/CodeGen/LiveRangeEdit.h7
-rw-r--r--include/llvm/CodeGen/LiveRegMatrix.h7
-rw-r--r--include/llvm/CodeGen/LiveRegUnits.h7
-rw-r--r--include/llvm/CodeGen/LiveStacks.h7
-rw-r--r--include/llvm/CodeGen/LiveVariables.h7
-rw-r--r--include/llvm/CodeGen/LoopTraversal.h7
-rw-r--r--include/llvm/CodeGen/LowLevelType.h7
-rw-r--r--include/llvm/CodeGen/MIRParser/MIParser.h233
-rw-r--r--include/llvm/CodeGen/MIRParser/MIRParser.h7
-rw-r--r--include/llvm/CodeGen/MIRPrinter.h9
-rw-r--r--include/llvm/CodeGen/MIRYamlMapping.h108
-rw-r--r--include/llvm/CodeGen/MachORelocation.h7
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h28
-rw-r--r--include/llvm/CodeGen/MachineBlockFrequencyInfo.h7
-rw-r--r--include/llvm/CodeGen/MachineBranchProbabilityInfo.h7
-rw-r--r--include/llvm/CodeGen/MachineCombinerPattern.h7
-rw-r--r--include/llvm/CodeGen/MachineConstantPool.h7
-rw-r--r--include/llvm/CodeGen/MachineDominanceFrontier.h7
-rw-r--r--include/llvm/CodeGen/MachineDominators.h7
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h14
-rw-r--r--include/llvm/CodeGen/MachineFunction.h76
-rw-r--r--include/llvm/CodeGen/MachineFunctionPass.h7
-rw-r--r--include/llvm/CodeGen/MachineInstr.h81
-rw-r--r--include/llvm/CodeGen/MachineInstrBuilder.h15
-rw-r--r--include/llvm/CodeGen/MachineInstrBundle.h15
-rw-r--r--include/llvm/CodeGen/MachineInstrBundleIterator.h7
-rw-r--r--include/llvm/CodeGen/MachineJumpTableInfo.h7
-rw-r--r--include/llvm/CodeGen/MachineLoopInfo.h7
-rw-r--r--include/llvm/CodeGen/MachineMemOperand.h26
-rw-r--r--include/llvm/CodeGen/MachineModuleInfo.h32
-rw-r--r--include/llvm/CodeGen/MachineModuleInfoImpls.h7
-rw-r--r--include/llvm/CodeGen/MachineOperand.h21
-rw-r--r--include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h21
-rw-r--r--include/llvm/CodeGen/MachineOutliner.h13
-rw-r--r--include/llvm/CodeGen/MachinePassRegistry.h7
-rw-r--r--include/llvm/CodeGen/MachinePipeliner.h85
-rw-r--r--include/llvm/CodeGen/MachinePostDominators.h9
-rw-r--r--include/llvm/CodeGen/MachineRegionInfo.h7
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h20
-rw-r--r--include/llvm/CodeGen/MachineSSAUpdater.h7
-rw-r--r--include/llvm/CodeGen/MachineScheduler.h35
-rw-r--r--include/llvm/CodeGen/MachineTraceMetrics.h7
-rw-r--r--include/llvm/CodeGen/MacroFusion.h7
-rw-r--r--include/llvm/CodeGen/PBQP/CostAllocator.h7
-rw-r--r--include/llvm/CodeGen/PBQP/Graph.h7
-rw-r--r--include/llvm/CodeGen/PBQP/Math.h7
-rw-r--r--include/llvm/CodeGen/PBQP/ReductionRules.h7
-rw-r--r--include/llvm/CodeGen/PBQP/Solution.h7
-rw-r--r--include/llvm/CodeGen/PBQPRAConstraint.h9
-rw-r--r--include/llvm/CodeGen/ParallelCG.h7
-rw-r--r--include/llvm/CodeGen/Passes.h15
-rw-r--r--include/llvm/CodeGen/PreISelIntrinsicLowering.h7
-rw-r--r--include/llvm/CodeGen/PseudoSourceValue.h10
-rw-r--r--include/llvm/CodeGen/ReachingDefAnalysis.h9
-rw-r--r--include/llvm/CodeGen/RegAllocPBQP.h7
-rw-r--r--include/llvm/CodeGen/RegAllocRegistry.h35
-rw-r--r--include/llvm/CodeGen/Register.h60
-rw-r--r--include/llvm/CodeGen/RegisterClassInfo.h7
-rw-r--r--include/llvm/CodeGen/RegisterPressure.h11
-rw-r--r--include/llvm/CodeGen/RegisterScavenging.h24
-rw-r--r--include/llvm/CodeGen/RegisterUsageInfo.h7
-rw-r--r--include/llvm/CodeGen/ResourcePriorityQueue.h7
-rw-r--r--include/llvm/CodeGen/RuntimeLibcalls.h7
-rw-r--r--include/llvm/CodeGen/SDNodeProperties.td7
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h31
-rw-r--r--include/llvm/CodeGen/ScheduleDAGInstrs.h23
-rw-r--r--include/llvm/CodeGen/ScheduleDAGMutation.h7
-rw-r--r--include/llvm/CodeGen/ScheduleDFS.h9
-rw-r--r--include/llvm/CodeGen/ScheduleHazardRecognizer.h7
-rw-r--r--include/llvm/CodeGen/SchedulerRegistry.h7
-rw-r--r--include/llvm/CodeGen/ScoreboardHazardRecognizer.h7
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h139
-rw-r--r--include/llvm/CodeGen/SelectionDAGAddressAnalysis.h46
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h15
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h185
-rw-r--r--include/llvm/CodeGen/SelectionDAGTargetInfo.h15
-rw-r--r--include/llvm/CodeGen/SlotIndexes.h87
-rw-r--r--include/llvm/CodeGen/StackMaps.h7
-rw-r--r--include/llvm/CodeGen/StackProtector.h13
-rw-r--r--include/llvm/CodeGen/SwiftErrorValueTracking.h110
-rw-r--r--include/llvm/CodeGen/SwitchLoweringUtils.h297
-rw-r--r--include/llvm/CodeGen/TailDuplicator.h7
-rw-r--r--include/llvm/CodeGen/TargetCallingConv.h23
-rw-r--r--include/llvm/CodeGen/TargetFrameLowering.h37
-rw-r--r--include/llvm/CodeGen/TargetInstrInfo.h46
-rw-r--r--include/llvm/CodeGen/TargetLowering.h375
-rw-r--r--include/llvm/CodeGen/TargetLoweringObjectFileImpl.h7
-rw-r--r--include/llvm/CodeGen/TargetOpcodes.h7
-rw-r--r--include/llvm/CodeGen/TargetPassConfig.h37
-rw-r--r--include/llvm/CodeGen/TargetRegisterInfo.h14
-rw-r--r--include/llvm/CodeGen/TargetSchedule.h7
-rw-r--r--include/llvm/CodeGen/TargetSubtargetInfo.h33
-rw-r--r--include/llvm/CodeGen/UnreachableBlockElim.h7
-rw-r--r--include/llvm/CodeGen/ValueTypes.h7
-rw-r--r--include/llvm/CodeGen/ValueTypes.td180
-rw-r--r--include/llvm/CodeGen/VirtRegMap.h17
-rw-r--r--include/llvm/CodeGen/WasmEHFuncInfo.h29
-rw-r--r--include/llvm/CodeGen/WinEHFuncInfo.h7
162 files changed, 4228 insertions, 1529 deletions
diff --git a/include/llvm/CodeGen/AccelTable.h b/include/llvm/CodeGen/AccelTable.h
index 13928582f2dd..734531a65d50 100644
--- a/include/llvm/CodeGen/AccelTable.h
+++ b/include/llvm/CodeGen/AccelTable.h
@@ -1,9 +1,8 @@
//==- include/llvm/CodeGen/AccelTable.h - Accelerator Tables -----*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -327,14 +326,8 @@ public:
void emit(AsmPrinter *Asm) const override;
-#ifndef _MSC_VER
- // The line below is rejected by older versions (TBD) of MSVC.
static constexpr Atom Atoms[] = {
Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)};
-#else
- // FIXME: Erase this path once the minimum MSCV version has been bumped.
- static const SmallVector<Atom, 4> Atoms;
-#endif
#ifndef NDEBUG
void print(raw_ostream &OS) const override;
@@ -352,16 +345,10 @@ public:
void emit(AsmPrinter *Asm) const override;
-#ifndef _MSC_VER
- // The line below is rejected by older versions (TBD) of MSVC.
static constexpr Atom Atoms[] = {
Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4),
Atom(dwarf::DW_ATOM_die_tag, dwarf::DW_FORM_data2),
Atom(dwarf::DW_ATOM_type_flags, dwarf::DW_FORM_data1)};
-#else
- // FIXME: Erase this path once the minimum MSCV version has been bumped.
- static const SmallVector<Atom, 4> Atoms;
-#endif
#ifndef NDEBUG
void print(raw_ostream &OS) const override;
@@ -376,14 +363,8 @@ public:
void emit(AsmPrinter *Asm) const override;
-#ifndef _MSC_VER
- // The line below is rejected by older versions (TBD) of MSVC.
static constexpr Atom Atoms[] = {
Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)};
-#else
- // FIXME: Erase this path once the minimum MSCV version has been bumped.
- static const SmallVector<Atom, 4> Atoms;
-#endif
#ifndef NDEBUG
void print(raw_ostream &OS) const override;
@@ -407,16 +388,10 @@ public:
void emit(AsmPrinter *Asm) const override;
-#ifndef _MSC_VER
- // The line below is rejected by older versions (TBD) of MSVC.
static constexpr Atom Atoms[] = {
Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4),
Atom(dwarf::DW_ATOM_die_tag, dwarf::DW_FORM_data2),
Atom(5, dwarf::DW_FORM_data1), Atom(6, dwarf::DW_FORM_data4)};
-#else
- // FIXME: Erase this path once the minimum MSCV version has been bumped.
- static const SmallVector<Atom, 4> Atoms;
-#endif
#ifndef NDEBUG
void print(raw_ostream &OS) const override;
diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h
index d77aee66ed76..0be0ac22a74d 100644
--- a/include/llvm/CodeGen/Analysis.h
+++ b/include/llvm/CodeGen/Analysis.h
@@ -1,9 +1,8 @@
//===- CodeGen/Analysis.h - CodeGen LLVM IR Analysis Utilities --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -26,6 +25,7 @@
namespace llvm {
class GlobalValue;
+class LLT;
class MachineBasicBlock;
class MachineFunction;
class TargetLoweringBase;
@@ -74,6 +74,25 @@ void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty,
SmallVectorImpl<uint64_t> *Offsets = nullptr,
uint64_t StartingOffset = 0);
+/// Variant of ComputeValueVTs that also produces the memory VTs.
+void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty,
+ SmallVectorImpl<EVT> &ValueVTs,
+ SmallVectorImpl<EVT> *MemVTs,
+ SmallVectorImpl<uint64_t> *Offsets = nullptr,
+ uint64_t StartingOffset = 0);
+
+/// computeValueLLTs - Given an LLVM IR type, compute a sequence of
+/// LLTs that represent all the individual underlying
+/// non-aggregate types that comprise it.
+///
+/// If Offsets is non-null, it points to a vector to be filled in
+/// with the in-memory offsets of each of the individual values.
+///
+void computeValueLLTs(const DataLayout &DL, Type &Ty,
+ SmallVectorImpl<LLT> &ValueTys,
+ SmallVectorImpl<uint64_t> *Offsets = nullptr,
+ uint64_t StartingOffset = 0);
+
/// ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V.
GlobalValue *ExtractTypeInfo(Value *V);
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 413901d218f9..d110f8b01cb5 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/AsmPrinter.h - AsmPrinter Framework ---------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -20,6 +19,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/CodeGen/AsmPrinterHandler.h"
#include "llvm/CodeGen/DwarfStringPoolEntry.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/IR/InlineAsm.h"
@@ -33,7 +33,6 @@
namespace llvm {
-class AsmPrinterHandler;
class BasicBlock;
class BlockAddress;
class Constant;
@@ -122,9 +121,6 @@ public:
using GOTEquivUsePair = std::pair<const GlobalVariable *, unsigned>;
MapVector<const MCSymbol *, GOTEquivUsePair> GlobalGOTEquivs;
- /// Enable print [latency:throughput] in output.
- bool EnablePrintSchedInfo = false;
-
private:
MCSymbol *CurrentFnBegin = nullptr;
MCSymbol *CurrentFnEnd = nullptr;
@@ -142,16 +138,16 @@ protected:
/// Protected struct HandlerInfo and Handlers permit target extended
/// AsmPrinter adds their own handlers.
struct HandlerInfo {
- AsmPrinterHandler *Handler;
+ std::unique_ptr<AsmPrinterHandler> Handler;
const char *TimerName;
const char *TimerDescription;
const char *TimerGroupName;
const char *TimerGroupDescription;
- HandlerInfo(AsmPrinterHandler *Handler, const char *TimerName,
- const char *TimerDescription, const char *TimerGroupName,
- const char *TimerGroupDescription)
- : Handler(Handler), TimerName(TimerName),
+ HandlerInfo(std::unique_ptr<AsmPrinterHandler> Handler,
+ const char *TimerName, const char *TimerDescription,
+ const char *TimerGroupName, const char *TimerGroupDescription)
+ : Handler(std::move(Handler)), TimerName(TimerName),
TimerDescription(TimerDescription), TimerGroupName(TimerGroupName),
TimerGroupDescription(TimerGroupDescription) {}
};
@@ -227,6 +223,9 @@ public:
void EmitToStreamer(MCStreamer &S, const MCInst &Inst);
+ /// Emits inital debug location directive.
+ void emitInitialRawDwarfLocDirective(const MachineFunction &MF);
+
/// Return the current section we are emitting to.
const MCSection *getCurrentSection() const;
@@ -316,6 +315,8 @@ public:
void emitStackSizeSection(const MachineFunction &MF);
+ void emitRemarksSection(Module &M);
+
enum CFIMoveType { CFI_M_None, CFI_M_EH, CFI_M_Debug };
CFIMoveType needsCFIMoves() const;
@@ -511,7 +512,7 @@ public:
void EmitSLEB128(int64_t Value, const char *Desc = nullptr) const;
/// Emit the specified unsigned leb128 value.
- void EmitULEB128(uint64_t Value, const char *Desc = nullptr) const;
+ void EmitULEB128(uint64_t Value, const char *Desc = nullptr, unsigned PadTo = 0) const;
/// Emit a .byte 42 directive that corresponds to an encoding. If verbose
/// assembly output is enabled, we output comments describing the encoding.
@@ -542,6 +543,12 @@ public:
emitDwarfStringOffset(S.getEntry());
}
+ /// Emit reference to a call site with a specified encoding
+ void EmitCallSiteOffset(const MCSymbol *Hi, const MCSymbol *Lo,
+ unsigned Encoding) const;
+ /// Emit an integer value corresponding to the call site encoding
+ void EmitCallSiteValue(uint64_t Value, unsigned Encoding) const;
+
/// Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified.
virtual unsigned getISAEncoding() { return 0; }
@@ -589,20 +596,22 @@ public:
virtual void PrintSpecial(const MachineInstr *MI, raw_ostream &OS,
const char *Code) const;
+ /// Print the MachineOperand as a symbol. Targets with complex handling of
+ /// symbol references should override the base implementation.
+ virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS);
+
/// Print the specified operand of MI, an INLINEASM instruction, using the
/// specified assembler variant. Targets should override this to format as
/// appropriate. This method can return true if the operand is erroneous.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode,
- raw_ostream &OS);
+ const char *ExtraCode, raw_ostream &OS);
/// Print the specified operand of MI, an INLINEASM instruction, using the
/// specified assembler variant as an address. Targets should override this to
/// format as appropriate. This method can return true if the operand is
/// erroneous.
virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode,
- raw_ostream &OS);
+ const char *ExtraCode, raw_ostream &OS);
/// Let the target do anything it needs to do before emitting inlineasm.
/// \p StartInfo - the subtarget info before parsing inline asm
@@ -617,6 +626,15 @@ public:
virtual void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
const MCSubtargetInfo *EndInfo) const;
+ /// This emits visibility information about symbol, if this is supported by
+ /// the target.
+ void EmitVisibility(MCSymbol *Sym, unsigned Visibility,
+ bool IsDefinition = true) const;
+
+ /// This emits linkage information about \p GVSym based on \p GV, if this is
+ /// supported by the target.
+ void EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const;
+
private:
/// Private state for PrintSpecial()
// Assign a unique ID to this machine instruction.
@@ -647,13 +665,6 @@ private:
// Internal Implementation Details
//===------------------------------------------------------------------===//
- /// This emits visibility information about symbol, if this is supported by
- /// the target.
- void EmitVisibility(MCSymbol *Sym, unsigned Visibility,
- bool IsDefinition = true) const;
-
- void EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const;
-
void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
const MachineBasicBlock *MBB, unsigned uid) const;
void EmitLLVMUsedList(const ConstantArray *InitList);
diff --git a/include/llvm/CodeGen/AsmPrinterHandler.h b/include/llvm/CodeGen/AsmPrinterHandler.h
index a8b13200dd4e..affb558f2fa6 100644
--- a/include/llvm/CodeGen/AsmPrinterHandler.h
+++ b/include/llvm/CodeGen/AsmPrinterHandler.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/AsmPrinterHandler.h -----------------------*- C++ -*--===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/AtomicExpandUtils.h b/include/llvm/CodeGen/AtomicExpandUtils.h
index b1adf66e7ff4..8a46c6e00d22 100644
--- a/include/llvm/CodeGen/AtomicExpandUtils.h
+++ b/include/llvm/CodeGen/AtomicExpandUtils.h
@@ -1,9 +1,8 @@
//===- AtomicExpandUtils.h - Utilities for expanding atomic instructions --===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/BasicTTIImpl.h b/include/llvm/CodeGen/BasicTTIImpl.h
index f105d887c397..70bf670fdf0b 100644
--- a/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/include/llvm/CodeGen/BasicTTIImpl.h
@@ -1,9 +1,8 @@
//===- BasicTTIImpl.h -------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -197,11 +196,12 @@ protected:
public:
/// \name Scalar TTI Implementations
/// @{
- bool allowsMisalignedMemoryAccesses(LLVMContext &Context,
- unsigned BitWidth, unsigned AddressSpace,
- unsigned Alignment, bool *Fast) const {
+ bool allowsMisalignedMemoryAccesses(LLVMContext &Context, unsigned BitWidth,
+ unsigned AddressSpace, unsigned Alignment,
+ bool *Fast) const {
EVT E = EVT::getIntegerVT(Context, BitWidth);
- return getTLI()->allowsMisalignedMemoryAccesses(E, AddressSpace, Alignment, Fast);
+ return getTLI()->allowsMisalignedMemoryAccesses(
+ E, AddressSpace, Alignment, MachineMemOperand::MONone, Fast);
}
bool hasBranchDivergence() { return false; }
@@ -293,12 +293,12 @@ public:
}
unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<const Value *> Arguments) {
- return BaseT::getIntrinsicCost(IID, RetTy, Arguments);
+ ArrayRef<const Value *> Arguments, const User *U) {
+ return BaseT::getIntrinsicCost(IID, RetTy, Arguments, U);
}
unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<Type *> ParamTys) {
+ ArrayRef<Type *> ParamTys, const User *U) {
if (IID == Intrinsic::cttz) {
if (getTLI()->isCheapToSpeculateCttz())
return TargetTransformInfo::TCC_Basic;
@@ -311,7 +311,7 @@ public:
return TargetTransformInfo::TCC_Expensive;
}
- return BaseT::getIntrinsicCost(IID, RetTy, ParamTys);
+ return BaseT::getIntrinsicCost(IID, RetTy, ParamTys, U);
}
unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI,
@@ -414,6 +414,12 @@ public:
if (TLI->isZExtFree(OpTy, Ty))
return TargetTransformInfo::TCC_Free;
return TargetTransformInfo::TCC_Basic;
+
+ case Instruction::AddrSpaceCast:
+ if (TLI->isFreeAddrSpaceCast(OpTy->getPointerAddressSpace(),
+ Ty->getPointerAddressSpace()))
+ return TargetTransformInfo::TCC_Free;
+ return TargetTransformInfo::TCC_Basic;
}
return BaseT::getOperationCost(Opcode, Ty, OpTy);
@@ -421,6 +427,8 @@ public:
unsigned getInliningThresholdMultiplier() { return 1; }
+ int getInlinerVectorBonusPercent() { return 150; }
+
void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
TTI::UnrollingPreferences &UP) {
// This unrolling functionality is target independent, but to provide some
@@ -486,6 +494,13 @@ public:
UP.BEInsns = 2;
}
+ bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
+ AssumptionCache &AC,
+ TargetLibraryInfo *LibInfo,
+ HardwareLoopInfo &HWLoopInfo) {
+ return BaseT::isHardwareLoopProfitable(L, SE, AC, LibInfo, HWLoopInfo);
+ }
+
int getInstructionLatency(const Instruction *I) {
if (isa<LoadInst>(I))
return getST()->getSchedModel().DefaultLoadLatency;
@@ -657,7 +672,7 @@ public:
return 0;
if (Opcode == Instruction::AddrSpaceCast &&
- TLI->isNoopAddrSpaceCast(Src->getPointerAddressSpace(),
+ TLI->isFreeAddrSpaceCast(Src->getPointerAddressSpace(),
Dst->getPointerAddressSpace()))
return 0;
@@ -997,7 +1012,7 @@ public:
// inside the loop.
if (UseMaskForGaps)
Cost += static_cast<T *>(this)->getArithmeticInstrCost(
- BinaryOperator::And, MaskVT);
+ BinaryOperator::And, MaskVT);
return Cost;
}
@@ -1058,8 +1073,8 @@ public:
case Intrinsic::experimental_vector_reduce_and:
case Intrinsic::experimental_vector_reduce_or:
case Intrinsic::experimental_vector_reduce_xor:
- case Intrinsic::experimental_vector_reduce_fadd:
- case Intrinsic::experimental_vector_reduce_fmul:
+ case Intrinsic::experimental_vector_reduce_v2_fadd:
+ case Intrinsic::experimental_vector_reduce_v2_fmul:
case Intrinsic::experimental_vector_reduce_smax:
case Intrinsic::experimental_vector_reduce_smin:
case Intrinsic::experimental_vector_reduce_fmax:
@@ -1116,6 +1131,9 @@ public:
unsigned getIntrinsicInstrCost(
Intrinsic::ID IID, Type *RetTy, ArrayRef<Type *> Tys, FastMathFlags FMF,
unsigned ScalarizationCostPassed = std::numeric_limits<unsigned>::max()) {
+ unsigned RetVF = (RetTy->isVectorTy() ? RetTy->getVectorNumElements() : 1);
+ auto *ConcreteTTI = static_cast<T *>(this);
+
SmallVector<unsigned, 2> ISDs;
unsigned SingleCallCost = 10; // Library call cost. Make it expensive.
switch (IID) {
@@ -1144,8 +1162,8 @@ public:
if (ScalarCalls == 1)
return 1; // Return cost of a scalar intrinsic. Assume it to be cheap.
- unsigned ScalarCost = static_cast<T *>(this)->getIntrinsicInstrCost(
- IID, ScalarRetTy, ScalarTys, FMF);
+ unsigned ScalarCost =
+ ConcreteTTI->getIntrinsicInstrCost(IID, ScalarRetTy, ScalarTys, FMF);
return ScalarCalls * ScalarCost + ScalarizationCost;
}
@@ -1227,44 +1245,181 @@ public:
case Intrinsic::sideeffect:
return 0;
case Intrinsic::masked_store:
- return static_cast<T *>(this)
- ->getMaskedMemoryOpCost(Instruction::Store, Tys[0], 0, 0);
+ return ConcreteTTI->getMaskedMemoryOpCost(Instruction::Store, Tys[0], 0,
+ 0);
case Intrinsic::masked_load:
- return static_cast<T *>(this)
- ->getMaskedMemoryOpCost(Instruction::Load, RetTy, 0, 0);
+ return ConcreteTTI->getMaskedMemoryOpCost(Instruction::Load, RetTy, 0, 0);
case Intrinsic::experimental_vector_reduce_add:
- return static_cast<T *>(this)->getArithmeticReductionCost(
- Instruction::Add, Tys[0], /*IsPairwiseForm=*/false);
+ return ConcreteTTI->getArithmeticReductionCost(Instruction::Add, Tys[0],
+ /*IsPairwiseForm=*/false);
case Intrinsic::experimental_vector_reduce_mul:
- return static_cast<T *>(this)->getArithmeticReductionCost(
- Instruction::Mul, Tys[0], /*IsPairwiseForm=*/false);
+ return ConcreteTTI->getArithmeticReductionCost(Instruction::Mul, Tys[0],
+ /*IsPairwiseForm=*/false);
case Intrinsic::experimental_vector_reduce_and:
- return static_cast<T *>(this)->getArithmeticReductionCost(
- Instruction::And, Tys[0], /*IsPairwiseForm=*/false);
+ return ConcreteTTI->getArithmeticReductionCost(Instruction::And, Tys[0],
+ /*IsPairwiseForm=*/false);
case Intrinsic::experimental_vector_reduce_or:
- return static_cast<T *>(this)->getArithmeticReductionCost(
- Instruction::Or, Tys[0], /*IsPairwiseForm=*/false);
+ return ConcreteTTI->getArithmeticReductionCost(Instruction::Or, Tys[0],
+ /*IsPairwiseForm=*/false);
case Intrinsic::experimental_vector_reduce_xor:
- return static_cast<T *>(this)->getArithmeticReductionCost(
- Instruction::Xor, Tys[0], /*IsPairwiseForm=*/false);
- case Intrinsic::experimental_vector_reduce_fadd:
- return static_cast<T *>(this)->getArithmeticReductionCost(
- Instruction::FAdd, Tys[0], /*IsPairwiseForm=*/false);
- case Intrinsic::experimental_vector_reduce_fmul:
- return static_cast<T *>(this)->getArithmeticReductionCost(
- Instruction::FMul, Tys[0], /*IsPairwiseForm=*/false);
+ return ConcreteTTI->getArithmeticReductionCost(Instruction::Xor, Tys[0],
+ /*IsPairwiseForm=*/false);
+ case Intrinsic::experimental_vector_reduce_v2_fadd:
+ return ConcreteTTI->getArithmeticReductionCost(
+ Instruction::FAdd, Tys[0],
+ /*IsPairwiseForm=*/false); // FIXME: Add new flag for cost of strict
+ // reductions.
+ case Intrinsic::experimental_vector_reduce_v2_fmul:
+ return ConcreteTTI->getArithmeticReductionCost(
+ Instruction::FMul, Tys[0],
+ /*IsPairwiseForm=*/false); // FIXME: Add new flag for cost of strict
+ // reductions.
case Intrinsic::experimental_vector_reduce_smax:
case Intrinsic::experimental_vector_reduce_smin:
case Intrinsic::experimental_vector_reduce_fmax:
case Intrinsic::experimental_vector_reduce_fmin:
- return static_cast<T *>(this)->getMinMaxReductionCost(
+ return ConcreteTTI->getMinMaxReductionCost(
Tys[0], CmpInst::makeCmpResultType(Tys[0]), /*IsPairwiseForm=*/false,
- /*IsSigned=*/true);
+ /*IsUnsigned=*/true);
case Intrinsic::experimental_vector_reduce_umax:
case Intrinsic::experimental_vector_reduce_umin:
- return static_cast<T *>(this)->getMinMaxReductionCost(
+ return ConcreteTTI->getMinMaxReductionCost(
Tys[0], CmpInst::makeCmpResultType(Tys[0]), /*IsPairwiseForm=*/false,
- /*IsSigned=*/false);
+ /*IsUnsigned=*/false);
+ case Intrinsic::sadd_sat:
+ case Intrinsic::ssub_sat: {
+ Type *CondTy = Type::getInt1Ty(RetTy->getContext());
+ if (RetVF > 1)
+ CondTy = VectorType::get(CondTy, RetVF);
+
+ Type *OpTy = StructType::create({RetTy, CondTy});
+ Intrinsic::ID OverflowOp = IID == Intrinsic::sadd_sat
+ ? Intrinsic::sadd_with_overflow
+ : Intrinsic::ssub_with_overflow;
+
+ // SatMax -> Overflow && SumDiff < 0
+ // SatMin -> Overflow && SumDiff >= 0
+ unsigned Cost = 0;
+ Cost += ConcreteTTI->getIntrinsicInstrCost(
+ OverflowOp, OpTy, {RetTy, RetTy}, FMF, ScalarizationCostPassed);
+ Cost += ConcreteTTI->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy,
+ CondTy, nullptr);
+ Cost += 2 * ConcreteTTI->getCmpSelInstrCost(BinaryOperator::Select, RetTy,
+ CondTy, nullptr);
+ return Cost;
+ }
+ case Intrinsic::uadd_sat:
+ case Intrinsic::usub_sat: {
+ Type *CondTy = Type::getInt1Ty(RetTy->getContext());
+ if (RetVF > 1)
+ CondTy = VectorType::get(CondTy, RetVF);
+
+ Type *OpTy = StructType::create({RetTy, CondTy});
+ Intrinsic::ID OverflowOp = IID == Intrinsic::uadd_sat
+ ? Intrinsic::uadd_with_overflow
+ : Intrinsic::usub_with_overflow;
+
+ unsigned Cost = 0;
+ Cost += ConcreteTTI->getIntrinsicInstrCost(
+ OverflowOp, OpTy, {RetTy, RetTy}, FMF, ScalarizationCostPassed);
+ Cost += ConcreteTTI->getCmpSelInstrCost(BinaryOperator::Select, RetTy,
+ CondTy, nullptr);
+ return Cost;
+ }
+ case Intrinsic::smul_fix:
+ case Intrinsic::umul_fix: {
+ unsigned ExtSize = RetTy->getScalarSizeInBits() * 2;
+ Type *ExtTy = Type::getIntNTy(RetTy->getContext(), ExtSize);
+ if (RetVF > 1)
+ ExtTy = VectorType::get(ExtTy, RetVF);
+
+ unsigned ExtOp =
+ IID == Intrinsic::smul_fix ? Instruction::SExt : Instruction::ZExt;
+
+ unsigned Cost = 0;
+ Cost += 2 * ConcreteTTI->getCastInstrCost(ExtOp, ExtTy, RetTy);
+ Cost += ConcreteTTI->getArithmeticInstrCost(Instruction::Mul, ExtTy);
+ Cost +=
+ 2 * ConcreteTTI->getCastInstrCost(Instruction::Trunc, RetTy, ExtTy);
+ Cost += ConcreteTTI->getArithmeticInstrCost(Instruction::LShr, RetTy,
+ TTI::OK_AnyValue,
+ TTI::OK_UniformConstantValue);
+ Cost += ConcreteTTI->getArithmeticInstrCost(Instruction::Shl, RetTy,
+ TTI::OK_AnyValue,
+ TTI::OK_UniformConstantValue);
+ Cost += ConcreteTTI->getArithmeticInstrCost(Instruction::Or, RetTy);
+ return Cost;
+ }
+ case Intrinsic::sadd_with_overflow:
+ case Intrinsic::ssub_with_overflow: {
+ Type *SumTy = RetTy->getContainedType(0);
+ Type *OverflowTy = RetTy->getContainedType(1);
+ unsigned Opcode = IID == Intrinsic::sadd_with_overflow
+ ? BinaryOperator::Add
+ : BinaryOperator::Sub;
+
+ // LHSSign -> LHS >= 0
+ // RHSSign -> RHS >= 0
+ // SumSign -> Sum >= 0
+ //
+ // Add:
+ // Overflow -> (LHSSign == RHSSign) && (LHSSign != SumSign)
+ // Sub:
+ // Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign)
+ unsigned Cost = 0;
+ Cost += ConcreteTTI->getArithmeticInstrCost(Opcode, SumTy);
+ Cost += 3 * ConcreteTTI->getCmpSelInstrCost(BinaryOperator::ICmp, SumTy,
+ OverflowTy, nullptr);
+ Cost += 2 * ConcreteTTI->getCmpSelInstrCost(
+ BinaryOperator::ICmp, OverflowTy, OverflowTy, nullptr);
+ Cost +=
+ ConcreteTTI->getArithmeticInstrCost(BinaryOperator::And, OverflowTy);
+ return Cost;
+ }
+ case Intrinsic::uadd_with_overflow:
+ case Intrinsic::usub_with_overflow: {
+ Type *SumTy = RetTy->getContainedType(0);
+ Type *OverflowTy = RetTy->getContainedType(1);
+ unsigned Opcode = IID == Intrinsic::uadd_with_overflow
+ ? BinaryOperator::Add
+ : BinaryOperator::Sub;
+
+ unsigned Cost = 0;
+ Cost += ConcreteTTI->getArithmeticInstrCost(Opcode, SumTy);
+ Cost += ConcreteTTI->getCmpSelInstrCost(BinaryOperator::ICmp, SumTy,
+ OverflowTy, nullptr);
+ return Cost;
+ }
+ case Intrinsic::smul_with_overflow:
+ case Intrinsic::umul_with_overflow: {
+ Type *MulTy = RetTy->getContainedType(0);
+ Type *OverflowTy = RetTy->getContainedType(1);
+ unsigned ExtSize = MulTy->getScalarSizeInBits() * 2;
+ Type *ExtTy = Type::getIntNTy(RetTy->getContext(), ExtSize);
+ if (MulTy->isVectorTy())
+ ExtTy = VectorType::get(ExtTy, MulTy->getVectorNumElements() );
+
+ unsigned ExtOp =
+ IID == Intrinsic::smul_fix ? Instruction::SExt : Instruction::ZExt;
+
+ unsigned Cost = 0;
+ Cost += 2 * ConcreteTTI->getCastInstrCost(ExtOp, ExtTy, MulTy);
+ Cost += ConcreteTTI->getArithmeticInstrCost(Instruction::Mul, ExtTy);
+ Cost +=
+ 2 * ConcreteTTI->getCastInstrCost(Instruction::Trunc, MulTy, ExtTy);
+ Cost += ConcreteTTI->getArithmeticInstrCost(Instruction::LShr, MulTy,
+ TTI::OK_AnyValue,
+ TTI::OK_UniformConstantValue);
+
+ if (IID == Intrinsic::smul_with_overflow)
+ Cost += ConcreteTTI->getArithmeticInstrCost(
+ Instruction::AShr, MulTy, TTI::OK_AnyValue,
+ TTI::OK_UniformConstantValue);
+
+ Cost += ConcreteTTI->getCmpSelInstrCost(BinaryOperator::ICmp, MulTy,
+ OverflowTy, nullptr);
+ return Cost;
+ }
case Intrinsic::ctpop:
ISDs.push_back(ISD::CTPOP);
// In case of legalization use TCC_Expensive. This is cheaper than a
@@ -1305,17 +1460,16 @@ public:
if (MinLegalCostI != LegalCost.end())
return *MinLegalCostI;
- auto MinCustomCostI = std::min_element(CustomCost.begin(), CustomCost.end());
+ auto MinCustomCostI =
+ std::min_element(CustomCost.begin(), CustomCost.end());
if (MinCustomCostI != CustomCost.end())
return *MinCustomCostI;
// If we can't lower fmuladd into an FMA estimate the cost as a floating
// point mul followed by an add.
if (IID == Intrinsic::fmuladd)
- return static_cast<T *>(this)
- ->getArithmeticInstrCost(BinaryOperator::FMul, RetTy) +
- static_cast<T *>(this)
- ->getArithmeticInstrCost(BinaryOperator::FAdd, RetTy);
+ return ConcreteTTI->getArithmeticInstrCost(BinaryOperator::FMul, RetTy) +
+ ConcreteTTI->getArithmeticInstrCost(BinaryOperator::FAdd, RetTy);
// Else, assume that we need to scalarize this intrinsic. For math builtins
// this will emit a costly libcall, adding call overhead and spills. Make it
@@ -1333,7 +1487,7 @@ public:
Ty = Ty->getScalarType();
ScalarTys.push_back(Ty);
}
- unsigned ScalarCost = static_cast<T *>(this)->getIntrinsicInstrCost(
+ unsigned ScalarCost = ConcreteTTI->getIntrinsicInstrCost(
IID, RetTy->getScalarType(), ScalarTys, FMF);
for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) {
if (Tys[i]->isVectorTy()) {
diff --git a/include/llvm/CodeGen/BuiltinGCs.h b/include/llvm/CodeGen/BuiltinGCs.h
index 1767922fb5ac..d44183dab0f7 100644
--- a/include/llvm/CodeGen/BuiltinGCs.h
+++ b/include/llvm/CodeGen/BuiltinGCs.h
@@ -1,9 +1,8 @@
//===-- BuiltinGCs.h - Garbage collector linkage hacks --------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/CSEConfigBase.h b/include/llvm/CodeGen/CSEConfigBase.h
new file mode 100644
index 000000000000..70b5e5c17eb1
--- /dev/null
+++ b/include/llvm/CodeGen/CSEConfigBase.h
@@ -0,0 +1,28 @@
+//===- CSEConfigBase.h - A CSEConfig interface ------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_CSECONFIG_BASE_H
+#define LLVM_CODEGEN_CSECONFIG_BASE_H
+
+namespace llvm {
+// Class representing some configuration that can be done during GlobalISel's
+// CSEInfo analysis. We define it here because TargetPassConfig can't depend on
+// the GlobalISel library, and so we use this in the interface between them
+// so that the derived classes in GISel can reference generic opcodes.
+class CSEConfigBase {
+public:
+ virtual ~CSEConfigBase() = default;
+ // Hook for defining which Generic instructions should be CSEd.
+ // GISelCSEInfo currently only calls this hook when dealing with generic
+ // opcodes.
+ virtual bool shouldCSEOpc(unsigned Opc) { return false; }
+};
+
+} // namespace llvm
+
+#endif // LLVM_CODEGEN_CSECONFIG_BASE_H
diff --git a/include/llvm/CodeGen/CalcSpillWeights.h b/include/llvm/CodeGen/CalcSpillWeights.h
index f85767f1fc11..9b8b7324f30a 100644
--- a/include/llvm/CodeGen/CalcSpillWeights.h
+++ b/include/llvm/CodeGen/CalcSpillWeights.h
@@ -1,9 +1,8 @@
//===- lib/CodeGen/CalcSpillWeights.h ---------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h
index efcf80ba0b4e..aa339e1cc913 100644
--- a/include/llvm/CodeGen/CallingConvLower.h
+++ b/include/llvm/CodeGen/CallingConvLower.h
@@ -1,9 +1,8 @@
//===- llvm/CallingConvLower.h - Calling Conventions ------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -146,7 +145,7 @@ public:
bool needsCustom() const { return isCustom; }
- unsigned getLocReg() const { assert(isRegLoc()); return Loc; }
+ Register getLocReg() const { assert(isRegLoc()); return Loc; }
unsigned getLocMemOffset() const { assert(isMemLoc()); return Loc; }
unsigned getExtraInfo() const { return Loc; }
MVT getLocVT() const { return LocVT; }
@@ -557,7 +556,7 @@ public:
// Sort the locations of the arguments according to their original position.
SmallVector<CCValAssign, 16> TmpArgLocs;
- std::swap(TmpArgLocs, Locs);
+ TmpArgLocs.swap(Locs);
auto B = TmpArgLocs.begin(), E = TmpArgLocs.end();
std::merge(B, B + NumFirstPassLocs, B + NumFirstPassLocs, E,
std::back_inserter(Locs),
diff --git a/include/llvm/CodeGen/CommandFlags.inc b/include/llvm/CodeGen/CommandFlags.inc
index 568d329a5e8c..cb69e9f61405 100644
--- a/include/llvm/CodeGen/CommandFlags.inc
+++ b/include/llvm/CodeGen/CommandFlags.inc
@@ -1,9 +1,8 @@
//===-- CommandFlags.h - Command Line Flags Interface -----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -272,6 +271,11 @@ static cl::opt<bool>
EnableAddrsig("addrsig", cl::desc("Emit an address-significance table"),
cl::init(false));
+static cl::opt<bool>
+ EnableDebugEntryValues("debug-entry-values",
+ cl::desc("Emit debug info about parameter's entry values"),
+ cl::init(false));
+
// Common utility function tightly tied to the options listed here. Initializes
// a TargetOptions object with CodeGen flags and returns it.
static TargetOptions InitTargetOptionsFromCodeGenFlags() {
@@ -301,6 +305,7 @@ static TargetOptions InitTargetOptionsFromCodeGenFlags() {
Options.ExceptionModel = ExceptionModel;
Options.EmitStackSizeSection = EnableStackSizeSection;
Options.EmitAddrsig = EnableAddrsig;
+ Options.EnableDebugEntryValues = EnableDebugEntryValues;
Options.MCOptions = InitMCTargetOptionsFromFlags();
diff --git a/include/llvm/CodeGen/CostTable.h b/include/llvm/CodeGen/CostTable.h
index 48ad76971520..52f3bfaea180 100644
--- a/include/llvm/CodeGen/CostTable.h
+++ b/include/llvm/CodeGen/CostTable.h
@@ -1,9 +1,8 @@
//===-- CostTable.h - Instruction Cost Table handling -----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/llvm/CodeGen/DAGCombine.h b/include/llvm/CodeGen/DAGCombine.h
index 8b5919005451..944187341455 100644
--- a/include/llvm/CodeGen/DAGCombine.h
+++ b/include/llvm/CodeGen/DAGCombine.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/DAGCombine.h ------- SelectionDAG Nodes ---*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/DFAPacketizer.h b/include/llvm/CodeGen/DFAPacketizer.h
index d3aabe22f216..cf58ee0cabea 100644
--- a/include/llvm/CodeGen/DFAPacketizer.h
+++ b/include/llvm/CodeGen/DFAPacketizer.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/DFAPacketizer.h - DFA Packetizer for VLIW ---*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// This class implements a deterministic finite automaton (DFA) based
diff --git a/include/llvm/CodeGen/DIE.h b/include/llvm/CodeGen/DIE.h
index 7d486b1df56d..684f9e40ca5a 100644
--- a/include/llvm/CodeGen/DIE.h
+++ b/include/llvm/CodeGen/DIE.h
@@ -1,9 +1,8 @@
//===- lib/CodeGen/DIE.h - DWARF Info Entries -------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -39,6 +38,7 @@ namespace llvm {
class AsmPrinter;
class DIE;
class DIEUnit;
+class DwarfCompileUnit;
class MCExpr;
class MCSection;
class MCSymbol;
@@ -231,6 +231,25 @@ public:
};
//===--------------------------------------------------------------------===//
+/// A BaseTypeRef DIE.
+class DIEBaseTypeRef {
+ const DwarfCompileUnit *CU;
+ const uint64_t Index;
+ static constexpr unsigned ULEB128PadSize = 4;
+
+public:
+ explicit DIEBaseTypeRef(const DwarfCompileUnit *TheCU, uint64_t Idx)
+ : CU(TheCU), Index(Idx) {}
+
+ /// EmitValue - Emit base type reference.
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ /// SizeOf - Determine size of the base type reference in bytes.
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
+
+ void print(raw_ostream &O) const;
+};
+
+//===--------------------------------------------------------------------===//
/// A simple label difference DIE.
///
class DIEDelta {
@@ -350,7 +369,7 @@ private:
/// should be stored by reference instead of by value.
using ValTy = AlignedCharArrayUnion<DIEInteger, DIEString, DIEExpr, DIELabel,
DIEDelta *, DIEEntry, DIEBlock *,
- DIELoc *, DIELocList>;
+ DIELoc *, DIELocList, DIEBaseTypeRef *>;
static_assert(sizeof(ValTy) <= sizeof(uint64_t) ||
sizeof(ValTy) <= sizeof(void *),
@@ -502,6 +521,18 @@ struct IntrusiveBackListBase {
}
Last = &N;
}
+
+ void push_front(Node &N) {
+ assert(N.Next.getPointer() == &N && "Expected unlinked node");
+ assert(N.Next.getInt() == true && "Expected unlinked node");
+
+ if (Last) {
+ N.Next.setPointerAndInt(Last->Next.getPointer(), false);
+ Last->Next.setPointerAndInt(&N, true);
+ } else {
+ Last = &N;
+ }
+ }
};
template <class T> class IntrusiveBackList : IntrusiveBackListBase {
@@ -509,8 +540,15 @@ public:
using IntrusiveBackListBase::empty;
void push_back(T &N) { IntrusiveBackListBase::push_back(N); }
+ void push_front(T &N) { IntrusiveBackListBase::push_front(N); }
T &back() { return *static_cast<T *>(Last); }
const T &back() const { return *static_cast<T *>(Last); }
+ T &front() {
+ return *static_cast<T *>(Last ? Last->Next.getPointer() : nullptr);
+ }
+ const T &front() const {
+ return *static_cast<T *>(Last ? Last->Next.getPointer() : nullptr);
+ }
class const_iterator;
class iterator
@@ -760,7 +798,7 @@ public:
///
/// \returns the DIEUnit that represents the compile or type unit that owns
/// this DIE, or NULL if this DIE hasn't been added to a unit DIE.
- const DIEUnit *getUnit() const;
+ DIEUnit *getUnit() const;
void setOffset(unsigned O) { Offset = O; }
void setSize(unsigned S) { Size = S; }
@@ -773,6 +811,13 @@ public:
return Children.back();
}
+ DIE &addChildFront(DIE *Child) {
+ assert(!Child->getParent() && "Child should be orphaned");
+ Child->Owner = this;
+ Children.push_front(*Child);
+ return Children.front();
+ }
+
/// Find a value in the DIE with the attribute given.
///
/// Returns a default-constructed DIEValue (where \a DIEValue::getType()
@@ -800,7 +845,7 @@ class DIEUnit {
const uint16_t Version; /// The Dwarf version number for this unit.
const uint8_t AddrSize; /// The size in bytes of an address for this unit.
protected:
- ~DIEUnit() = default;
+ virtual ~DIEUnit() = default;
public:
DIEUnit(uint16_t Version, uint8_t AddrSize, dwarf::Tag UnitTag);
diff --git a/include/llvm/CodeGen/DIEValue.def b/include/llvm/CodeGen/DIEValue.def
index a3fce9b1d20c..92afeb3868b4 100644
--- a/include/llvm/CodeGen/DIEValue.def
+++ b/include/llvm/CodeGen/DIEValue.def
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/DIEValue.def - DIEValue types ---------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -35,6 +34,7 @@ HANDLE_DIEVALUE_SMALL(Integer)
HANDLE_DIEVALUE_SMALL(String)
HANDLE_DIEVALUE_SMALL(Expr)
HANDLE_DIEVALUE_SMALL(Label)
+HANDLE_DIEVALUE_LARGE(BaseTypeRef)
HANDLE_DIEVALUE_LARGE(Delta)
HANDLE_DIEVALUE_SMALL(Entry)
HANDLE_DIEVALUE_LARGE(Block)
diff --git a/include/llvm/CodeGen/DbgEntityHistoryCalculator.h b/include/llvm/CodeGen/DbgEntityHistoryCalculator.h
index befc28f084e7..7eec75bc81bf 100644
--- a/include/llvm/CodeGen/DbgEntityHistoryCalculator.h
+++ b/include/llvm/CodeGen/DbgEntityHistoryCalculator.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/DbgEntityHistoryCalculator.h ----------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -11,6 +10,7 @@
#define LLVM_CODEGEN_DBGVALUEHISTORYCALCULATOR_H
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include <utility>
@@ -22,35 +22,76 @@ class MachineFunction;
class MachineInstr;
class TargetRegisterInfo;
-// For each user variable, keep a list of instruction ranges where this variable
-// is accessible. The variables are listed in order of appearance.
+/// For each user variable, keep a list of instruction ranges where this
+/// variable is accessible. The variables are listed in order of appearance.
class DbgValueHistoryMap {
- // Each instruction range starts with a DBG_VALUE instruction, specifying the
- // location of a variable, which is assumed to be valid until the end of the
- // range. If end is not specified, location is valid until the start
- // instruction of the next instruction range, or until the end of the
- // function.
public:
- using InstrRange = std::pair<const MachineInstr *, const MachineInstr *>;
- using InstrRanges = SmallVector<InstrRange, 4>;
+ /// Index in the entry vector.
+ typedef size_t EntryIndex;
+
+ /// Special value to indicate that an entry is valid until the end of the
+ /// function.
+ static const EntryIndex NoEntry = std::numeric_limits<EntryIndex>::max();
+
+ /// Specifies a change in a variable's debug value history.
+ ///
+ /// There exist two types of entries:
+ ///
+ /// * Debug value entry:
+ ///
+ /// A new debug value becomes live. If the entry's \p EndIndex is \p NoEntry,
+ /// the value is valid until the end of the function. For other values, the
+ /// index points to the entry in the entry vector that ends this debug
+ /// value. The ending entry can either be an overlapping debug value, or
+ /// an instruction that clobbers the value.
+ ///
+ /// * Clobbering entry:
+ ///
+ /// This entry's instruction clobbers one or more preceding
+ /// register-described debug values that have their end index
+ /// set to this entry's position in the entry vector.
+ class Entry {
+ public:
+ enum EntryKind { DbgValue, Clobber };
+
+ Entry(const MachineInstr *Instr, EntryKind Kind)
+ : Instr(Instr, Kind), EndIndex(NoEntry) {}
+
+ const MachineInstr *getInstr() const { return Instr.getPointer(); }
+ EntryIndex getEndIndex() const { return EndIndex; }
+ EntryKind getEntryKind() const { return Instr.getInt(); }
+
+ bool isClobber() const { return getEntryKind() == Clobber; }
+ bool isDbgValue() const { return getEntryKind() == DbgValue; }
+ bool isClosed() const { return EndIndex != NoEntry; }
+
+ void endEntry(EntryIndex EndIndex);
+
+ private:
+ PointerIntPair<const MachineInstr *, 1, EntryKind> Instr;
+ EntryIndex EndIndex;
+ };
+ using Entries = SmallVector<Entry, 4>;
using InlinedEntity = std::pair<const DINode *, const DILocation *>;
- using InstrRangesMap = MapVector<InlinedEntity, InstrRanges>;
+ using EntriesMap = MapVector<InlinedEntity, Entries>;
private:
- InstrRangesMap VarInstrRanges;
+ EntriesMap VarEntries;
public:
- void startInstrRange(InlinedEntity Var, const MachineInstr &MI);
- void endInstrRange(InlinedEntity Var, const MachineInstr &MI);
+ bool startDbgValue(InlinedEntity Var, const MachineInstr &MI,
+ EntryIndex &NewIndex);
+ EntryIndex startClobber(InlinedEntity Var, const MachineInstr &MI);
- // Returns register currently describing @Var. If @Var is currently
- // unaccessible or is not described by a register, returns 0.
- unsigned getRegisterForVar(InlinedEntity Var) const;
+ Entry &getEntry(InlinedEntity Var, EntryIndex Index) {
+ auto &Entries = VarEntries[Var];
+ return Entries[Index];
+ }
- bool empty() const { return VarInstrRanges.empty(); }
- void clear() { VarInstrRanges.clear(); }
- InstrRangesMap::const_iterator begin() const { return VarInstrRanges.begin(); }
- InstrRangesMap::const_iterator end() const { return VarInstrRanges.end(); }
+ bool empty() const { return VarEntries.empty(); }
+ void clear() { VarEntries.clear(); }
+ EntriesMap::const_iterator begin() const { return VarEntries.begin(); }
+ EntriesMap::const_iterator end() const { return VarEntries.end(); }
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void dump() const;
diff --git a/include/llvm/CodeGen/DebugHandlerBase.h b/include/llvm/CodeGen/DebugHandlerBase.h
index 4f0d14d317f2..4008d597395e 100644
--- a/include/llvm/CodeGen/DebugHandlerBase.h
+++ b/include/llvm/CodeGen/DebugHandlerBase.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/DebugHandlerBase.h -----------------------*- C++ -*--===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -130,7 +129,7 @@ public:
const MCExpr *getFunctionLocalOffsetAfterInsn(const MachineInstr *MI);
/// If this type is derived from a base type then return base type size.
- static uint64_t getBaseTypeSize(const DITypeRef TyRef);
+ static uint64_t getBaseTypeSize(const DIType *Ty);
};
}
diff --git a/include/llvm/CodeGen/DwarfStringPoolEntry.h b/include/llvm/CodeGen/DwarfStringPoolEntry.h
index 8b1a7af17bbf..e189352a7b2d 100644
--- a/include/llvm/CodeGen/DwarfStringPoolEntry.h
+++ b/include/llvm/CodeGen/DwarfStringPoolEntry.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/DwarfStringPoolEntry.h - String pool entry --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/EdgeBundles.h b/include/llvm/CodeGen/EdgeBundles.h
index c31fad246c96..28cdf54e0575 100644
--- a/include/llvm/CodeGen/EdgeBundles.h
+++ b/include/llvm/CodeGen/EdgeBundles.h
@@ -1,9 +1,8 @@
//===-------- EdgeBundles.h - Bundles of CFG edges --------------*- c++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/ExecutionDomainFix.h b/include/llvm/CodeGen/ExecutionDomainFix.h
index 338c214dd073..6836678e2101 100644
--- a/include/llvm/CodeGen/ExecutionDomainFix.h
+++ b/include/llvm/CodeGen/ExecutionDomainFix.h
@@ -1,9 +1,8 @@
//==-- llvm/CodeGen/ExecutionDomainFix.h - Execution Domain Fix -*- C++ -*--==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/ExpandReductions.h b/include/llvm/CodeGen/ExpandReductions.h
index c6aaaad967b3..5dbed07873c1 100644
--- a/include/llvm/CodeGen/ExpandReductions.h
+++ b/include/llvm/CodeGen/ExpandReductions.h
@@ -1,9 +1,8 @@
//===----- ExpandReductions.h - Expand experimental reduction intrinsics --===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h
index 865d8a88b8cc..f09b59daf4dd 100644
--- a/include/llvm/CodeGen/FastISel.h
+++ b/include/llvm/CodeGen/FastISel.h
@@ -1,9 +1,8 @@
//===- FastISel.h - Definition of the FastISel class ------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
@@ -528,7 +527,7 @@ protected:
/// Select and emit code for a binary operator instruction, which has
/// an opcode which directly corresponds to the given ISD opcode.
bool selectBinaryOp(const User *I, unsigned ISDOpcode);
- bool selectFNeg(const User *I);
+ bool selectFNeg(const User *I, const Value *In);
bool selectGetElementPtr(const User *I);
bool selectStackmap(const CallInst *I);
bool selectPatchpoint(const CallInst *I);
diff --git a/include/llvm/CodeGen/FaultMaps.h b/include/llvm/CodeGen/FaultMaps.h
index 55e25c9823b1..a1e2349c413e 100644
--- a/include/llvm/CodeGen/FaultMaps.h
+++ b/include/llvm/CodeGen/FaultMaps.h
@@ -1,9 +1,8 @@
//===- FaultMaps.h - The "FaultMaps" section --------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h
index 7c658515de09..fb60191abd3a 100644
--- a/include/llvm/CodeGen/FunctionLoweringInfo.h
+++ b/include/llvm/CodeGen/FunctionLoweringInfo.h
@@ -1,9 +1,8 @@
//===- FunctionLoweringInfo.h - Lower functions from LLVM IR ---*- C++ -*--===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -14,13 +13,14 @@
#ifndef LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H
#define LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H
-
#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Analysis/LegacyDivergenceAnalysis.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
@@ -57,6 +57,7 @@ public:
const TargetLowering *TLI;
MachineRegisterInfo *RegInfo;
BranchProbabilityInfo *BPI;
+ const LegacyDivergenceAnalysis *DA;
/// CanLowerReturn - true iff the function's return value can be lowered to
/// registers.
bool CanLowerReturn;
@@ -71,48 +72,6 @@ public:
/// MBBMap - A mapping from LLVM basic blocks to their machine code entry.
DenseMap<const BasicBlock*, MachineBasicBlock *> MBBMap;
- /// A map from swifterror value in a basic block to the virtual register it is
- /// currently represented by.
- DenseMap<std::pair<const MachineBasicBlock *, const Value *>, unsigned>
- SwiftErrorVRegDefMap;
-
- /// A list of upward exposed vreg uses that need to be satisfied by either a
- /// copy def or a phi node at the beginning of the basic block representing
- /// the predecessor(s) swifterror value.
- DenseMap<std::pair<const MachineBasicBlock *, const Value *>, unsigned>
- SwiftErrorVRegUpwardsUse;
-
- /// A map from instructions that define/use a swifterror value to the virtual
- /// register that represents that def/use.
- llvm::DenseMap<PointerIntPair<const Instruction *, 1, bool>, unsigned>
- SwiftErrorVRegDefUses;
-
- /// The swifterror argument of the current function.
- const Value *SwiftErrorArg;
-
- using SwiftErrorValues = SmallVector<const Value*, 1>;
- /// A function can only have a single swifterror argument. And if it does
- /// have a swifterror argument, it must be the first entry in
- /// SwiftErrorVals.
- SwiftErrorValues SwiftErrorVals;
-
- /// Get or create the swifterror value virtual register in
- /// SwiftErrorVRegDefMap for this basic block.
- unsigned getOrCreateSwiftErrorVReg(const MachineBasicBlock *,
- const Value *);
-
- /// Set the swifterror virtual register in the SwiftErrorVRegDefMap for this
- /// basic block.
- void setCurrentSwiftErrorVReg(const MachineBasicBlock *MBB, const Value *,
- unsigned);
-
- /// Get or create the swifterror value virtual register for a def of a
- /// swifterror by an instruction.
- std::pair<unsigned, bool> getOrCreateSwiftErrorVRegDefAt(const Instruction *);
- std::pair<unsigned, bool>
- getOrCreateSwiftErrorVRegUseAt(const Instruction *, const MachineBasicBlock *,
- const Value *);
-
/// ValueMap - Since we emit code for the function a basic block at a time,
/// we must remember which virtual registers hold the values for
/// cross-basic-block values.
@@ -175,6 +134,10 @@ public:
/// function arguments that are inserted after scheduling is completed.
SmallVector<MachineInstr*, 8> ArgDbgValues;
+ /// Bitvector with a bit set if corresponding argument is described in
+ /// ArgDbgValues. Using arg numbers according to Argument numbering.
+ BitVector DescribedArgs;
+
/// RegFixups - Registers which need to be replaced after isel is done.
DenseMap<unsigned, unsigned> RegFixups;
@@ -236,9 +199,11 @@ public:
return ValueMap.count(V);
}
- unsigned CreateReg(MVT VT);
+ unsigned CreateReg(MVT VT, bool isDivergent = false);
+
+ unsigned CreateRegs(const Value *V);
- unsigned CreateRegs(Type *Ty);
+ unsigned CreateRegs(Type *Ty, bool isDivergent = false);
unsigned InitializeRegForValue(const Value *V) {
// Tokens never live in vregs.
@@ -247,7 +212,7 @@ public:
unsigned &R = ValueMap[V];
assert(R == 0 && "Already initialized this value register!");
assert(VirtReg2Value.empty());
- return R = CreateRegs(V->getType());
+ return R = CreateRegs(V);
}
/// GetLiveOutRegInfo - Gets LiveOutInfo for a register, returning NULL if the
diff --git a/include/llvm/CodeGen/GCMetadata.h b/include/llvm/CodeGen/GCMetadata.h
index 7fb27202c122..77cd356c49dd 100644
--- a/include/llvm/CodeGen/GCMetadata.h
+++ b/include/llvm/CodeGen/GCMetadata.h
@@ -1,9 +1,8 @@
//===- GCMetadata.h - Garbage collector metadata ----------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/GCMetadataPrinter.h b/include/llvm/CodeGen/GCMetadataPrinter.h
index 5f1efb2ce02c..f9527c9f8752 100644
--- a/include/llvm/CodeGen/GCMetadataPrinter.h
+++ b/include/llvm/CodeGen/GCMetadataPrinter.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/GCMetadataPrinter.h - Prints asm GC tables --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/GCStrategy.h b/include/llvm/CodeGen/GCStrategy.h
index 5a60cd7cb823..c5731528da4e 100644
--- a/include/llvm/CodeGen/GCStrategy.h
+++ b/include/llvm/CodeGen/GCStrategy.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/GCStrategy.h - Garbage collection -----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/GlobalISel/CSEInfo.h b/include/llvm/CodeGen/GlobalISel/CSEInfo.h
index ce2d285a99e5..5a44e67992ad 100644
--- a/include/llvm/CodeGen/GlobalISel/CSEInfo.h
+++ b/include/llvm/CodeGen/GlobalISel/CSEInfo.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/GlobalISel/CSEInfo.h ------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -14,6 +13,7 @@
#define LLVM_CODEGEN_GLOBALISEL_CSEINFO_H
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/CodeGen/CSEConfigBase.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
#include "llvm/CodeGen/GlobalISel/GISelWorkList.h"
#include "llvm/CodeGen/GlobalISel/Utils.h"
@@ -37,25 +37,27 @@ public:
void Profile(FoldingSetNodeID &ID);
};
-// Class representing some configuration that can be done during CSE analysis.
-// Currently it only supports shouldCSE method that each pass can set.
-class CSEConfig {
+// A CSE config for fully optimized builds.
+class CSEConfigFull : public CSEConfigBase {
public:
- virtual ~CSEConfig() = default;
- // Hook for defining which Generic instructions should be CSEd.
- // GISelCSEInfo currently only calls this hook when dealing with generic
- // opcodes.
- virtual bool shouldCSEOpc(unsigned Opc);
+ virtual ~CSEConfigFull() = default;
+ virtual bool shouldCSEOpc(unsigned Opc) override;
};
-// TODO: Find a better place for this.
// Commonly used for O0 config.
-class CSEConfigConstantOnly : public CSEConfig {
+class CSEConfigConstantOnly : public CSEConfigBase {
public:
virtual ~CSEConfigConstantOnly() = default;
virtual bool shouldCSEOpc(unsigned Opc) override;
};
+// Returns the standard expected CSEConfig for the given optimization level.
+// We have this logic here so targets can make use of it from their derived
+// TargetPassConfig, but can't put this logic into TargetPassConfig directly
+// because the CodeGen library can't depend on GlobalISel.
+std::unique_ptr<CSEConfigBase>
+getStandardCSEConfigForOpt(CodeGenOpt::Level Level);
+
/// The CSE Analysis object.
/// This installs itself as a delegate to the MachineFunction to track
/// new instructions as well as deletions. It however will not be able to
@@ -74,7 +76,7 @@ class GISelCSEInfo : public GISelChangeObserver {
FoldingSet<UniqueMachineInstr> CSEMap;
MachineRegisterInfo *MRI = nullptr;
MachineFunction *MF = nullptr;
- std::unique_ptr<CSEConfig> CSEOpt;
+ std::unique_ptr<CSEConfigBase> CSEOpt;
/// Keep a cache of UniqueInstrs for each MachineInstr. In GISel,
/// often instructions are mutated (while their ID has completely changed).
/// Whenever mutation happens, invalidate the UniqueMachineInstr for the
@@ -139,7 +141,9 @@ public:
void releaseMemory();
- void setCSEConfig(std::unique_ptr<CSEConfig> Opt) { CSEOpt = std::move(Opt); }
+ void setCSEConfig(std::unique_ptr<CSEConfigBase> Opt) {
+ CSEOpt = std::move(Opt);
+ }
bool shouldCSE(unsigned Opc) const;
@@ -199,11 +203,12 @@ class GISelCSEAnalysisWrapper {
bool AlreadyComputed = false;
public:
- /// Takes a CSEConfig object that defines what opcodes get CSEd.
+ /// Takes a CSEConfigBase object that defines what opcodes get CSEd.
/// If CSEConfig is already set, and the CSE Analysis has been preserved,
/// it will not use the new CSEOpt(use Recompute to force using the new
/// CSEOpt).
- GISelCSEInfo &get(std::unique_ptr<CSEConfig> CSEOpt, bool ReCompute = false);
+ GISelCSEInfo &get(std::unique_ptr<CSEConfigBase> CSEOpt,
+ bool ReCompute = false);
void setMF(MachineFunction &MFunc) { MF = &MFunc; }
void setComputed(bool Computed) { AlreadyComputed = Computed; }
void releaseMemory() { Info.releaseMemory(); }
diff --git a/include/llvm/CodeGen/GlobalISel/CSEMIRBuilder.h b/include/llvm/CodeGen/GlobalISel/CSEMIRBuilder.h
index a8fb736ebbb5..4f95335db74b 100644
--- a/include/llvm/CodeGen/GlobalISel/CSEMIRBuilder.h
+++ b/include/llvm/CodeGen/GlobalISel/CSEMIRBuilder.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/GlobalISel/CSEMIRBuilder.h --*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
diff --git a/include/llvm/CodeGen/GlobalISel/CallLowering.h b/include/llvm/CodeGen/GlobalISel/CallLowering.h
index ab498e8f070b..d717121ad78e 100644
--- a/include/llvm/CodeGen/GlobalISel/CallLowering.h
+++ b/include/llvm/CodeGen/GlobalISel/CallLowering.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/GlobalISel/CallLowering.h - Call lowering ---*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
@@ -16,6 +15,7 @@
#define LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/TargetCallingConv.h"
#include "llvm/IR/CallSite.h"
@@ -27,6 +27,7 @@
namespace llvm {
+class CCState;
class DataLayout;
class Function;
class MachineIRBuilder;
@@ -43,14 +44,19 @@ class CallLowering {
virtual void anchor();
public:
struct ArgInfo {
- unsigned Reg;
+ SmallVector<Register, 4> Regs;
Type *Ty;
ISD::ArgFlagsTy Flags;
bool IsFixed;
- ArgInfo(unsigned Reg, Type *Ty, ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy{},
- bool IsFixed = true)
- : Reg(Reg), Ty(Ty), Flags(Flags), IsFixed(IsFixed) {}
+ ArgInfo(ArrayRef<Register> Regs, Type *Ty,
+ ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy{}, bool IsFixed = true)
+ : Regs(Regs.begin(), Regs.end()), Ty(Ty), Flags(Flags),
+ IsFixed(IsFixed) {
+ // FIXME: We should have just one way of saying "no register".
+ assert((Ty->isVoidTy() == (Regs.empty() || Regs[0] == 0)) &&
+ "only void types should have no register");
+ }
};
/// Argument handling is mostly uniform between the four places that
@@ -66,24 +72,28 @@ public:
virtual ~ValueHandler() = default;
+ /// Returns true if the handler is dealing with formal arguments,
+ /// not with return values etc.
+ virtual bool isArgumentHandler() const { return false; }
+
/// Materialize a VReg containing the address of the specified
/// stack-based object. This is either based on a FrameIndex or
/// direct SP manipulation, depending on the context. \p MPO
/// should be initialized to an appropriate description of the
/// address created.
- virtual unsigned getStackAddress(uint64_t Size, int64_t Offset,
+ virtual Register getStackAddress(uint64_t Size, int64_t Offset,
MachinePointerInfo &MPO) = 0;
/// The specified value has been assigned to a physical register,
/// handle the appropriate COPY (either to or from) and mark any
/// relevant uses/defines as needed.
- virtual void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
+ virtual void assignValueToReg(Register ValVReg, Register PhysReg,
CCValAssign &VA) = 0;
/// The specified value has been assigned to a stack
/// location. Load or store it there, with appropriate extension
/// if necessary.
- virtual void assignValueToAddress(unsigned ValVReg, unsigned Addr,
+ virtual void assignValueToAddress(Register ValVReg, Register Addr,
uint64_t Size, MachinePointerInfo &MPO,
CCValAssign &VA) = 0;
@@ -98,7 +108,7 @@ public:
llvm_unreachable("Custom values not supported");
}
- unsigned extendRegister(unsigned ValReg, CCValAssign &VA);
+ Register extendRegister(Register ValReg, CCValAssign &VA);
virtual bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT,
CCValAssign::LocInfo LocInfo, const ArgInfo &Info,
@@ -130,39 +140,83 @@ protected:
void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL,
const FuncInfoTy &FuncInfo) const;
+ /// Generate instructions for packing \p SrcRegs into one big register
+ /// corresponding to the aggregate type \p PackedTy.
+ ///
+ /// \param SrcRegs should contain one virtual register for each base type in
+ /// \p PackedTy, as returned by computeValueLLTs.
+ ///
+ /// \return The packed register.
+ Register packRegs(ArrayRef<Register> SrcRegs, Type *PackedTy,
+ MachineIRBuilder &MIRBuilder) const;
+
+ /// Generate instructions for unpacking \p SrcReg into the \p DstRegs
+ /// corresponding to the aggregate type \p PackedTy.
+ ///
+ /// \param DstRegs should contain one virtual register for each base type in
+ /// \p PackedTy, as returned by computeValueLLTs.
+ void unpackRegs(ArrayRef<Register> DstRegs, Register SrcReg, Type *PackedTy,
+ MachineIRBuilder &MIRBuilder) const;
+
/// Invoke Handler::assignArg on each of the given \p Args and then use
/// \p Callback to move them to the assigned locations.
///
/// \return True if everything has succeeded, false otherwise.
bool handleAssignments(MachineIRBuilder &MIRBuilder, ArrayRef<ArgInfo> Args,
ValueHandler &Handler) const;
-
+ bool handleAssignments(CCState &CCState,
+ SmallVectorImpl<CCValAssign> &ArgLocs,
+ MachineIRBuilder &MIRBuilder, ArrayRef<ArgInfo> Args,
+ ValueHandler &Handler) const;
public:
CallLowering(const TargetLowering *TLI) : TLI(TLI) {}
virtual ~CallLowering() = default;
+ /// \return true if the target is capable of handling swifterror values that
+ /// have been promoted to a specified register. The extended versions of
+ /// lowerReturn and lowerCall should be implemented.
+ virtual bool supportSwiftError() const {
+ return false;
+ }
+
/// This hook must be implemented to lower outgoing return values, described
/// by \p Val, into the specified virtual registers \p VRegs.
/// This hook is used by GlobalISel.
///
+ /// \p SwiftErrorVReg is non-zero if the function has a swifterror parameter
+ /// that needs to be implicitly returned.
+ ///
/// \return True if the lowering succeeds, false otherwise.
virtual bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
- ArrayRef<unsigned> VRegs) const {
+ ArrayRef<Register> VRegs,
+ Register SwiftErrorVReg) const {
+ if (!supportSwiftError()) {
+ assert(SwiftErrorVReg == 0 && "attempt to use unsupported swifterror");
+ return lowerReturn(MIRBuilder, Val, VRegs);
+ }
+ return false;
+ }
+
+ /// This hook behaves as the extended lowerReturn function, but for targets
+ /// that do not support swifterror value promotion.
+ virtual bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
+ ArrayRef<Register> VRegs) const {
return false;
}
/// This hook must be implemented to lower the incoming (formal)
- /// arguments, described by \p Args, for GlobalISel. Each argument
- /// must end up in the related virtual register described by VRegs.
- /// In other words, the first argument should end up in VRegs[0],
- /// the second in VRegs[1], and so on.
+ /// arguments, described by \p VRegs, for GlobalISel. Each argument
+ /// must end up in the related virtual registers described by \p VRegs.
+ /// In other words, the first argument should end up in \c VRegs[0],
+ /// the second in \c VRegs[1], and so on. For each argument, there will be one
+ /// register for each non-aggregate type, as returned by \c computeValueLLTs.
/// \p MIRBuilder is set to the proper insertion for the argument
/// lowering.
///
/// \return True if the lowering succeeded, false otherwise.
virtual bool lowerFormalArguments(MachineIRBuilder &MIRBuilder,
const Function &F,
- ArrayRef<unsigned> VRegs) const {
+ ArrayRef<ArrayRef<Register>> VRegs) const {
return false;
}
@@ -174,20 +228,31 @@ public:
/// \p Callee is the destination of the call. It should be either a register,
/// globaladdress, or externalsymbol.
///
- /// \p ResTy is the type returned by the function
- ///
- /// \p ResReg is the generic virtual register that the returned
- /// value should be lowered into.
+ /// \p OrigRet is a descriptor for the return type of the function.
///
- /// \p ArgTys is a list of the types each member of \p ArgRegs has; used by
- /// the target to decide which register/stack slot should be allocated.
+ /// \p OrigArgs is a list of descriptors of the arguments passed to the
+ /// function.
///
- /// \p ArgRegs is a list of virtual registers containing each argument that
- /// needs to be passed.
+ /// \p SwiftErrorVReg is non-zero if the call has a swifterror inout
+ /// parameter, and contains the vreg that the swifterror should be copied into
+ /// after the call.
///
/// \return true if the lowering succeeded, false otherwise.
virtual bool lowerCall(MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv,
const MachineOperand &Callee, const ArgInfo &OrigRet,
+ ArrayRef<ArgInfo> OrigArgs,
+ Register SwiftErrorVReg) const {
+ if (!supportSwiftError()) {
+ assert(SwiftErrorVReg == 0 && "trying to use unsupported swifterror");
+ return lowerCall(MIRBuilder, CallConv, Callee, OrigRet, OrigArgs);
+ }
+ return false;
+ }
+
+ /// This hook behaves as the extended lowerCall function, but for targets that
+ /// do not support swifterror value promotion.
+ virtual bool lowerCall(MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv,
+ const MachineOperand &Callee, const ArgInfo &OrigRet,
ArrayRef<ArgInfo> OrigArgs) const {
return false;
}
@@ -197,11 +262,18 @@ public:
///
/// \p CI is the call/invoke instruction.
///
- /// \p ResReg is a register where the call's return value should be stored (or
- /// 0 if there is no return value).
+ /// \p ResRegs are the registers where the call's return value should be
+ /// stored (or 0 if there is no return value). There will be one register for
+ /// each non-aggregate type, as returned by \c computeValueLLTs.
+ ///
+ /// \p ArgRegs is a list of lists of virtual registers containing each
+ /// argument that needs to be passed (argument \c i should be placed in \c
+ /// ArgRegs[i]). For each argument, there will be one register for each
+ /// non-aggregate type, as returned by \c computeValueLLTs.
///
- /// \p ArgRegs is a list of virtual registers containing each argument that
- /// needs to be passed.
+ /// \p SwiftErrorVReg is non-zero if the call has a swifterror inout
+ /// parameter, and contains the vreg that the swifterror should be copied into
+ /// after the call.
///
/// \p GetCalleeReg is a callback to materialize a register for the callee if
/// the target determines it cannot jump to the destination based purely on \p
@@ -210,7 +282,8 @@ public:
///
/// \return true if the lowering succeeded, false otherwise.
bool lowerCall(MachineIRBuilder &MIRBuilder, ImmutableCallSite CS,
- unsigned ResReg, ArrayRef<unsigned> ArgRegs,
+ ArrayRef<Register> ResRegs,
+ ArrayRef<ArrayRef<Register>> ArgRegs, Register SwiftErrorVReg,
std::function<unsigned()> GetCalleeReg) const;
};
diff --git a/include/llvm/CodeGen/GlobalISel/Combiner.h b/include/llvm/CodeGen/GlobalISel/Combiner.h
index b097c7817762..efe8bdf93664 100644
--- a/include/llvm/CodeGen/GlobalISel/Combiner.h
+++ b/include/llvm/CodeGen/GlobalISel/Combiner.h
@@ -1,9 +1,8 @@
-//== ----- llvm/CodeGen/GlobalISel/Combiner.h --------------------- == //
+//== ----- llvm/CodeGen/GlobalISel/Combiner.h -------------------*- C++ -*-== //
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 6e9ac01c1ee2..0c50c9c5e0cf 100644
--- a/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/GlobalISel/CombinerHelper.h --------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===--------------------------------------------------------------------===//
//
@@ -18,6 +17,9 @@
#ifndef LLVM_CODEGEN_GLOBALISEL_COMBINER_HELPER_H
#define LLVM_CODEGEN_GLOBALISEL_COMBINER_HELPER_H
+#include "llvm/CodeGen/LowLevelType.h"
+#include "llvm/CodeGen/Register.h"
+
namespace llvm {
class GISelChangeObserver;
@@ -26,6 +28,12 @@ class MachineRegisterInfo;
class MachineInstr;
class MachineOperand;
+struct PreferredTuple {
+ LLT Ty; // The result type of the extend.
+ unsigned ExtendOpcode; // G_ANYEXT/G_SEXT/G_ZEXT
+ MachineInstr *MI;
+};
+
class CombinerHelper {
MachineIRBuilder &Builder;
MachineRegisterInfo &MRI;
@@ -35,20 +43,27 @@ public:
CombinerHelper(GISelChangeObserver &Observer, MachineIRBuilder &B);
/// MachineRegisterInfo::replaceRegWith() and inform the observer of the changes
- void replaceRegWith(MachineRegisterInfo &MRI, unsigned FromReg, unsigned ToReg) const;
+ void replaceRegWith(MachineRegisterInfo &MRI, Register FromReg, Register ToReg) const;
/// Replace a single register operand with a new register and inform the
/// observer of the changes.
void replaceRegOpWith(MachineRegisterInfo &MRI, MachineOperand &FromRegOp,
- unsigned ToReg) const;
+ Register ToReg) const;
/// If \p MI is COPY, try to combine it.
/// Returns true if MI changed.
bool tryCombineCopy(MachineInstr &MI);
+ bool matchCombineCopy(MachineInstr &MI);
+ void applyCombineCopy(MachineInstr &MI);
/// If \p MI is extend that consumes the result of a load, try to combine it.
/// Returns true if MI changed.
bool tryCombineExtendingLoads(MachineInstr &MI);
+ bool matchCombineExtendingLoads(MachineInstr &MI, PreferredTuple &MatchInfo);
+ void applyCombineExtendingLoads(MachineInstr &MI, PreferredTuple &MatchInfo);
+
+ bool matchCombineBr(MachineInstr &MI);
+ bool tryCombineBr(MachineInstr &MI);
/// Try to transform \p MI by using all of the above
/// combine functions. Returns true if changed.
diff --git a/include/llvm/CodeGen/GlobalISel/CombinerInfo.h b/include/llvm/CodeGen/GlobalISel/CombinerInfo.h
index d21aa3f725d9..3b09a8e2b479 100644
--- a/include/llvm/CodeGen/GlobalISel/CombinerInfo.h
+++ b/include/llvm/CodeGen/GlobalISel/CombinerInfo.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/GlobalISel/CombinerInfo.h ------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.h b/include/llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.h
index 220a571b21db..e817d9b4550e 100644
--- a/include/llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.h
+++ b/include/llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.h --*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
diff --git a/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h b/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h
index c8e8a7a5a7cb..e5691cb35174 100644
--- a/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h
+++ b/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h
@@ -1,9 +1,8 @@
-//===----- llvm/CodeGen/GlobalISel/GISelChangeObserver.h ------------------===//
+//===----- llvm/CodeGen/GlobalISel/GISelChangeObserver.h --------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -34,10 +33,17 @@ public:
/// An instruction is about to be erased.
virtual void erasingInstr(MachineInstr &MI) = 0;
- /// An instruction was created and inserted into the function.
+
+ /// An instruction has been created and inserted into the function.
+ /// Note that the instruction might not be a fully fledged instruction at this
+ /// point and won't be if the MachineFunction::Delegate is calling it. This is
+ /// because the delegate only sees the construction of the MachineInstr before
+ /// operands have been added.
virtual void createdInstr(MachineInstr &MI) = 0;
+
/// This instruction is about to be mutated in some way.
virtual void changingInstr(MachineInstr &MI) = 0;
+
/// This instruction was mutated in some way.
virtual void changedInstr(MachineInstr &MI) = 0;
diff --git a/include/llvm/CodeGen/GlobalISel/GISelWorkList.h b/include/llvm/CodeGen/GlobalISel/GISelWorkList.h
index 1571841a208d..b0bb519283b1 100644
--- a/include/llvm/CodeGen/GlobalISel/GISelWorkList.h
+++ b/include/llvm/CodeGen/GlobalISel/GISelWorkList.h
@@ -1,9 +1,8 @@
//===- GISelWorkList.h - Worklist for GISel passes ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -33,23 +32,61 @@ class GISelWorkList {
SmallVector<MachineInstr *, N> Worklist;
DenseMap<MachineInstr *, unsigned> WorklistMap;
+#ifndef NDEBUG
+ bool Finalized = true;
+#endif
+
public:
- GISelWorkList() {}
+ GISelWorkList() : WorklistMap(N) {}
bool empty() const { return WorklistMap.empty(); }
unsigned size() const { return WorklistMap.size(); }
+ // Since we don't know ahead of time how many instructions we're going to add
+ // to the worklist, and migrating densemap's elements is quite expensive
+ // everytime we resize, only insert to the smallvector (typically during the
+ // initial phase of populating lists). Before the worklist can be used,
+ // finalize should be called. Also assert with NDEBUG if list is ever used
+ // without finalizing. Note that unlike insert, we won't check for duplicates
+ // - so the ideal place to use this is during the initial prepopulating phase
+ // of most passes.
+ void deferred_insert(MachineInstr *I) {
+ Worklist.push_back(I);
+#ifndef NDEBUG
+ Finalized = false;
+#endif
+ }
+
+ // This should only be called when using deferred_insert.
+ // This asserts that the WorklistMap is empty, and then
+ // inserts all the elements in the Worklist into the map.
+ // It also asserts if there are any duplicate elements found.
+ void finalize() {
+ assert(WorklistMap.empty() && "Expecting empty worklistmap");
+ if (Worklist.size() > N)
+ WorklistMap.reserve(Worklist.size());
+ for (unsigned i = 0; i < Worklist.size(); ++i)
+ if (!WorklistMap.try_emplace(Worklist[i], i).second)
+ llvm_unreachable("Duplicate elements in the list");
+#ifndef NDEBUG
+ Finalized = true;
+#endif
+ }
+
/// Add the specified instruction to the worklist if it isn't already in it.
void insert(MachineInstr *I) {
+ assert(Finalized && "GISelWorkList used without finalizing");
if (WorklistMap.try_emplace(I, Worklist.size()).second)
Worklist.push_back(I);
}
/// Remove I from the worklist if it exists.
void remove(const MachineInstr *I) {
+ assert((Finalized || WorklistMap.empty()) && "Neither finalized nor empty");
auto It = WorklistMap.find(I);
- if (It == WorklistMap.end()) return; // Not in worklist.
+ if (It == WorklistMap.end())
+ return; // Not in worklist.
// Don't bother moving everything down, just null out the slot.
Worklist[It->second] = nullptr;
@@ -63,6 +100,7 @@ public:
}
MachineInstr *pop_back_val() {
+ assert(Finalized && "GISelWorkList used without finalizing");
MachineInstr *I;
do {
I = Worklist.pop_back_val();
diff --git a/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/include/llvm/CodeGen/GlobalISel/IRTranslator.h
index d1770bf6e4ce..8654ba83f08d 100644
--- a/include/llvm/CodeGen/GlobalISel/IRTranslator.h
+++ b/include/llvm/CodeGen/GlobalISel/IRTranslator.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/GlobalISel/IRTranslator.h - IRTranslator ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
@@ -23,7 +22,9 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
#include "llvm/CodeGen/GlobalISel/Types.h"
+#include "llvm/CodeGen/SwiftErrorValueTracking.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/SwitchLoweringUtils.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/Allocator.h"
#include <memory>
@@ -37,6 +38,7 @@ class CallInst;
class CallLowering;
class Constant;
class DataLayout;
+class FunctionLoweringInfo;
class Instruction;
class MachineBasicBlock;
class MachineFunction;
@@ -69,7 +71,7 @@ private:
public:
ValueToVRegInfo() = default;
- using VRegListT = SmallVector<unsigned, 1>;
+ using VRegListT = SmallVector<Register, 1>;
using OffsetListT = SmallVector<uint64_t, 1>;
using const_vreg_iterator =
@@ -164,6 +166,8 @@ private:
/// this function.
DenseMap<const AllocaInst *, int> FrameIndices;
+ SwiftErrorValueTracking SwiftError;
+
/// \name Methods for translating form LLVM IR to MachineInstr.
/// \see ::translate for general information on the translate methods.
/// @{
@@ -196,7 +200,7 @@ private:
/// the function.
///
/// \return true if the materialization succeeded.
- bool translate(const Constant &C, unsigned Reg);
+ bool translate(const Constant &C, Register Reg);
/// Translate an LLVM bitcast into generic IR. Either a COPY or a G_BITCAST is
/// emitted.
@@ -212,24 +216,27 @@ private:
bool translateMemfunc(const CallInst &CI, MachineIRBuilder &MIRBuilder,
unsigned ID);
- void getStackGuard(unsigned DstReg, MachineIRBuilder &MIRBuilder);
+ void getStackGuard(Register DstReg, MachineIRBuilder &MIRBuilder);
bool translateOverflowIntrinsic(const CallInst &CI, unsigned Op,
MachineIRBuilder &MIRBuilder);
+ /// Helper function for translateSimpleIntrinsic.
+ /// \return The generic opcode for \p IntrinsicID if \p IntrinsicID is a
+ /// simple intrinsic (ceil, fabs, etc.). Otherwise, returns
+ /// Intrinsic::not_intrinsic.
+ unsigned getSimpleIntrinsicOpcode(Intrinsic::ID ID);
+
+ /// Translates the intrinsics defined in getSimpleIntrinsicOpcode.
+ /// \return true if the translation succeeded.
+ bool translateSimpleIntrinsic(const CallInst &CI, Intrinsic::ID ID,
+ MachineIRBuilder &MIRBuilder);
+
bool translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
MachineIRBuilder &MIRBuilder);
bool translateInlineAsm(const CallInst &CI, MachineIRBuilder &MIRBuilder);
- // FIXME: temporary function to expose previous interface to call lowering
- // until it is refactored.
- /// Combines all component registers of \p V into a single scalar with size
- /// "max(Offsets) + last size".
- unsigned packRegs(const Value &V, MachineIRBuilder &MIRBuilder);
-
- void unpackRegs(const Value &V, unsigned Src, MachineIRBuilder &MIRBuilder);
-
/// Returns true if the value should be split into multiple LLTs.
/// If \p Offsets is given then the split type's offsets will be stored in it.
/// If \p Offsets is not empty it will be cleared first.
@@ -242,6 +249,8 @@ private:
bool translateInvoke(const User &U, MachineIRBuilder &MIRBuilder);
+ bool translateCallBr(const User &U, MachineIRBuilder &MIRBuilder);
+
bool translateLandingPad(const User &U, MachineIRBuilder &MIRBuilder);
/// Translate one of LLVM's cast instructions into MachineInstrs, with the
@@ -278,7 +287,42 @@ private:
/// \pre \p U is a branch instruction.
bool translateBr(const User &U, MachineIRBuilder &MIRBuilder);
+ // Begin switch lowering functions.
+ bool emitJumpTableHeader(SwitchCG::JumpTable &JT,
+ SwitchCG::JumpTableHeader &JTH,
+ MachineBasicBlock *HeaderBB);
+ void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *MBB);
+
+ void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
+ MachineIRBuilder &MIB);
+
+ bool lowerJumpTableWorkItem(SwitchCG::SwitchWorkListItem W,
+ MachineBasicBlock *SwitchMBB,
+ MachineBasicBlock *CurMBB,
+ MachineBasicBlock *DefaultMBB,
+ MachineIRBuilder &MIB,
+ MachineFunction::iterator BBI,
+ BranchProbability UnhandledProbs,
+ SwitchCG::CaseClusterIt I,
+ MachineBasicBlock *Fallthrough,
+ bool FallthroughUnreachable);
+
+ bool lowerSwitchRangeWorkItem(SwitchCG::CaseClusterIt I,
+ Value *Cond,
+ MachineBasicBlock *Fallthrough,
+ bool FallthroughUnreachable,
+ BranchProbability UnhandledProbs,
+ MachineBasicBlock *CurMBB,
+ MachineIRBuilder &MIB,
+ MachineBasicBlock *SwitchMBB);
+
+ bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W, Value *Cond,
+ MachineBasicBlock *SwitchMBB,
+ MachineBasicBlock *DefaultMBB,
+ MachineIRBuilder &MIB);
+
bool translateSwitch(const User &U, MachineIRBuilder &MIRBuilder);
+ // End switch lowering section.
bool translateIndirectBr(const User &U, MachineIRBuilder &MIRBuilder);
@@ -404,6 +448,7 @@ private:
bool translateAtomicCmpXchg(const User &U, MachineIRBuilder &MIRBuilder);
bool translateAtomicRMW(const User &U, MachineIRBuilder &MIRBuilder);
+ bool translateFence(const User &U, MachineIRBuilder &MIRBuilder);
// Stubs to keep the compiler happy while we implement the rest of the
// translation.
@@ -419,9 +464,6 @@ private:
bool translateCatchSwitch(const User &U, MachineIRBuilder &MIRBuilder) {
return false;
}
- bool translateFence(const User &U, MachineIRBuilder &MIRBuilder) {
- return false;
- }
bool translateAddrSpaceCast(const User &U, MachineIRBuilder &MIRBuilder) {
return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
}
@@ -466,19 +508,50 @@ private:
/// Current optimization remark emitter. Used to report failures.
std::unique_ptr<OptimizationRemarkEmitter> ORE;
+ FunctionLoweringInfo FuncInfo;
+
+ // True when either the Target Machine specifies no optimizations or the
+ // function has the optnone attribute.
+ bool EnableOpts = false;
+
+ /// Switch analysis and optimization.
+ class GISelSwitchLowering : public SwitchCG::SwitchLowering {
+ public:
+ GISelSwitchLowering(IRTranslator *irt, FunctionLoweringInfo &funcinfo)
+ : SwitchLowering(funcinfo), IRT(irt) {
+ assert(irt && "irt is null!");
+ }
+
+ virtual void addSuccessorWithProb(
+ MachineBasicBlock *Src, MachineBasicBlock *Dst,
+ BranchProbability Prob = BranchProbability::getUnknown()) override {
+ IRT->addSuccessorWithProb(Src, Dst, Prob);
+ }
+
+ virtual ~GISelSwitchLowering() = default;
+
+ private:
+ IRTranslator *IRT;
+ };
+
+ std::unique_ptr<GISelSwitchLowering> SL;
+
// * Insert all the code needed to materialize the constants
// at the proper place. E.g., Entry block or dominator block
// of each constant depending on how fancy we want to be.
// * Clear the different maps.
void finalizeFunction();
+ // Handle emitting jump tables for each basic block.
+ void finalizeBasicBlock();
+
/// Get the VRegs that represent \p Val.
/// Non-aggregate types have just one corresponding VReg and the list can be
/// used as a single "unsigned". Aggregates get flattened. If such VRegs do
/// not exist, they are created.
- ArrayRef<unsigned> getOrCreateVRegs(const Value &Val);
+ ArrayRef<Register> getOrCreateVRegs(const Value &Val);
- unsigned getOrCreateVReg(const Value &Val) {
+ Register getOrCreateVReg(const Value &Val) {
auto Regs = getOrCreateVRegs(Val);
if (Regs.empty())
return 0;
@@ -522,6 +595,14 @@ private:
return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first));
}
+ /// Return branch probability calculated by BranchProbabilityInfo for IR
+ /// blocks.
+ BranchProbability getEdgeProbability(const MachineBasicBlock *Src,
+ const MachineBasicBlock *Dst) const;
+
+ void addSuccessorWithProb(MachineBasicBlock *Src, MachineBasicBlock *Dst,
+ BranchProbability Prob);
+
public:
// Ctor, nothing fancy.
IRTranslator();
diff --git a/include/llvm/CodeGen/GlobalISel/InstructionSelect.h b/include/llvm/CodeGen/GlobalISel/InstructionSelect.h
index 01521c46ab6a..1af46e0a9e76 100644
--- a/include/llvm/CodeGen/GlobalISel/InstructionSelect.h
+++ b/include/llvm/CodeGen/GlobalISel/InstructionSelect.h
@@ -1,9 +1,8 @@
//== llvm/CodeGen/GlobalISel/InstructionSelect.h -----------------*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file This file describes the interface of the MachineFunctionPass
diff --git a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
index 471def7f45a3..e9b93be76754 100644
--- a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
+++ b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/GlobalISel/InstructionSelector.h ------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -139,6 +138,16 @@ enum {
/// - MMOIdx - MMO index
/// - Size - The size in bytes of the memory access
GIM_CheckMemorySizeEqualTo,
+
+ /// Check the address space of the memory access for the given machine memory
+ /// operand.
+ /// - InsnID - Instruction ID
+ /// - MMOIdx - MMO index
+ /// - NumAddrSpace - Number of valid address spaces
+ /// - AddrSpaceN - An allowed space of the memory access
+ /// - AddrSpaceN+1 ...
+ GIM_CheckMemoryAddressSpace,
+
/// Check the size of the memory access for the given machine memory operand
/// against the size of an operand.
/// - InsnID - Instruction ID
diff --git a/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h b/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
index 2003a79f6b20..e8ee4af0cb0b 100644
--- a/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
+++ b/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h --------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -371,6 +370,45 @@ bool InstructionSelector::executeMatchTable(
return false;
break;
}
+ case GIM_CheckMemoryAddressSpace: {
+ int64_t InsnID = MatchTable[CurrentIdx++];
+ int64_t MMOIdx = MatchTable[CurrentIdx++];
+ // This accepts a list of possible address spaces.
+ const int NumAddrSpace = MatchTable[CurrentIdx++];
+
+ if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
+ if (handleReject() == RejectAndGiveUp)
+ return false;
+ break;
+ }
+
+ // Need to still jump to the end of the list of address spaces if we find
+ // a match earlier.
+ const uint64_t LastIdx = CurrentIdx + NumAddrSpace;
+
+ const MachineMemOperand *MMO
+ = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
+ const unsigned MMOAddrSpace = MMO->getAddrSpace();
+
+ bool Success = false;
+ for (int I = 0; I != NumAddrSpace; ++I) {
+ unsigned AddrSpace = MatchTable[CurrentIdx++];
+ DEBUG_WITH_TYPE(
+ TgtInstructionSelector::getName(),
+ dbgs() << "addrspace(" << MMOAddrSpace << ") vs "
+ << AddrSpace << '\n');
+
+ if (AddrSpace == MMOAddrSpace) {
+ Success = true;
+ break;
+ }
+ }
+
+ CurrentIdx = LastIdx;
+ if (!Success && handleReject() == RejectAndGiveUp)
+ return false;
+ break;
+ }
case GIM_CheckMemorySizeEqualTo: {
int64_t InsnID = MatchTable[CurrentIdx++];
int64_t MMOIdx = MatchTable[CurrentIdx++];
@@ -438,15 +476,15 @@ bool InstructionSelector::executeMatchTable(
unsigned Size = MRI.getType(MO.getReg()).getSizeInBits();
if (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT &&
- MMO->getSize() * 8 != Size) {
+ MMO->getSizeInBits() != Size) {
if (handleReject() == RejectAndGiveUp)
return false;
} else if (MatcherOpcode == GIM_CheckMemorySizeLessThanLLT &&
- MMO->getSize() * 8 >= Size) {
+ MMO->getSizeInBits() >= Size) {
if (handleReject() == RejectAndGiveUp)
return false;
} else if (MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT &&
- MMO->getSize() * 8 <= Size)
+ MMO->getSizeInBits() <= Size)
if (handleReject() == RejectAndGiveUp)
return false;
@@ -479,17 +517,19 @@ bool InstructionSelector::executeMatchTable(
<< InsnID << "]->getOperand(" << OpIdx
<< "), SizeInBits=" << SizeInBits << ")\n");
assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+ MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
+ const LLT Ty = MRI.getType(MO.getReg());
+
// iPTR must be looked up in the target.
if (SizeInBits == 0) {
MachineFunction *MF = State.MIs[InsnID]->getParent()->getParent();
- SizeInBits = MF->getDataLayout().getPointerSizeInBits(0);
+ const unsigned AddrSpace = Ty.getAddressSpace();
+ SizeInBits = MF->getDataLayout().getPointerSizeInBits(AddrSpace);
}
assert(SizeInBits != 0 && "Pointer size must be known");
- MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
if (MO.isReg()) {
- const LLT &Ty = MRI.getType(MO.getReg());
if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits)
if (handleReject() == RejectAndGiveUp)
return false;
diff --git a/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h b/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
index 20bec7650179..a22778b8848c 100644
--- a/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
+++ b/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h -----*- C++ -*-//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// This file contains some helper functions which try to cleanup artifacts
@@ -29,6 +28,18 @@ class LegalizationArtifactCombiner {
MachineRegisterInfo &MRI;
const LegalizerInfo &LI;
+ static bool isArtifactCast(unsigned Opc) {
+ switch (Opc) {
+ case TargetOpcode::G_TRUNC:
+ case TargetOpcode::G_SEXT:
+ case TargetOpcode::G_ZEXT:
+ case TargetOpcode::G_ANYEXT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
public:
LegalizationArtifactCombiner(MachineIRBuilder &B, MachineRegisterInfo &MRI,
const LegalizerInfo &LI)
@@ -40,11 +51,11 @@ public:
return false;
Builder.setInstr(MI);
- unsigned DstReg = MI.getOperand(0).getReg();
- unsigned SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
+ Register DstReg = MI.getOperand(0).getReg();
+ Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
// aext(trunc x) - > aext/copy/trunc x
- unsigned TruncSrc;
+ Register TruncSrc;
if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;);
Builder.buildAnyExtOrTrunc(DstReg, TruncSrc);
@@ -53,7 +64,7 @@ public:
}
// aext([asz]ext x) -> [asz]ext x
- unsigned ExtSrc;
+ Register ExtSrc;
MachineInstr *ExtMI;
if (mi_match(SrcReg, MRI,
m_all_of(m_MInstr(ExtMI), m_any_of(m_GAnyExt(m_Reg(ExtSrc)),
@@ -63,6 +74,20 @@ public:
markInstAndDefDead(MI, *ExtMI, DeadInsts);
return true;
}
+
+ // Try to fold aext(g_constant) when the larger constant type is legal.
+ // Can't use MIPattern because we don't have a specific constant in mind.
+ auto *SrcMI = MRI.getVRegDef(SrcReg);
+ if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) {
+ const LLT &DstTy = MRI.getType(DstReg);
+ if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) {
+ auto &CstVal = SrcMI->getOperand(1);
+ Builder.buildConstant(
+ DstReg, CstVal.getCImm()->getValue().sext(DstTy.getSizeInBits()));
+ markInstAndDefDead(MI, *SrcMI, DeadInsts);
+ return true;
+ }
+ }
return tryFoldImplicitDef(MI, DeadInsts);
}
@@ -73,25 +98,39 @@ public:
return false;
Builder.setInstr(MI);
- unsigned DstReg = MI.getOperand(0).getReg();
- unsigned SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
+ Register DstReg = MI.getOperand(0).getReg();
+ Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
// zext(trunc x) - > and (aext/copy/trunc x), mask
- unsigned TruncSrc;
+ Register TruncSrc;
if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
LLT DstTy = MRI.getType(DstReg);
if (isInstUnsupported({TargetOpcode::G_AND, {DstTy}}) ||
- isInstUnsupported({TargetOpcode::G_CONSTANT, {DstTy}}))
+ isConstantUnsupported(DstTy))
return false;
LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;);
LLT SrcTy = MRI.getType(SrcReg);
- APInt Mask = APInt::getAllOnesValue(SrcTy.getSizeInBits());
+ APInt Mask = APInt::getAllOnesValue(SrcTy.getScalarSizeInBits());
auto MIBMask = Builder.buildConstant(DstTy, Mask.getZExtValue());
Builder.buildAnd(DstReg, Builder.buildAnyExtOrTrunc(DstTy, TruncSrc),
MIBMask);
markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
return true;
}
+
+ // Try to fold zext(g_constant) when the larger constant type is legal.
+ // Can't use MIPattern because we don't have a specific constant in mind.
+ auto *SrcMI = MRI.getVRegDef(SrcReg);
+ if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) {
+ const LLT &DstTy = MRI.getType(DstReg);
+ if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) {
+ auto &CstVal = SrcMI->getOperand(1);
+ Builder.buildConstant(
+ DstReg, CstVal.getCImm()->getValue().zext(DstTy.getSizeInBits()));
+ markInstAndDefDead(MI, *SrcMI, DeadInsts);
+ return true;
+ }
+ }
return tryFoldImplicitDef(MI, DeadInsts);
}
@@ -102,20 +141,22 @@ public:
return false;
Builder.setInstr(MI);
- unsigned DstReg = MI.getOperand(0).getReg();
- unsigned SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
+ Register DstReg = MI.getOperand(0).getReg();
+ Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
// sext(trunc x) - > ashr (shl (aext/copy/trunc x), c), c
- unsigned TruncSrc;
+ Register TruncSrc;
if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
LLT DstTy = MRI.getType(DstReg);
- if (isInstUnsupported({TargetOpcode::G_SHL, {DstTy}}) ||
- isInstUnsupported({TargetOpcode::G_ASHR, {DstTy}}) ||
- isInstUnsupported({TargetOpcode::G_CONSTANT, {DstTy}}))
+ // Guess on the RHS shift amount type, which should be re-legalized if
+ // applicable.
+ if (isInstUnsupported({TargetOpcode::G_SHL, {DstTy, DstTy}}) ||
+ isInstUnsupported({TargetOpcode::G_ASHR, {DstTy, DstTy}}) ||
+ isConstantUnsupported(DstTy))
return false;
LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;);
LLT SrcTy = MRI.getType(SrcReg);
- unsigned ShAmt = DstTy.getSizeInBits() - SrcTy.getSizeInBits();
+ unsigned ShAmt = DstTy.getScalarSizeInBits() - SrcTy.getScalarSizeInBits();
auto MIBShAmt = Builder.buildConstant(DstTy, ShAmt);
auto MIBShl = Builder.buildInstr(
TargetOpcode::G_SHL, {DstTy},
@@ -138,7 +179,7 @@ public:
if (MachineInstr *DefMI = getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF,
MI.getOperand(1).getReg(), MRI)) {
Builder.setInstr(MI);
- unsigned DstReg = MI.getOperand(0).getReg();
+ Register DstReg = MI.getOperand(0).getReg();
LLT DstTy = MRI.getType(DstReg);
if (Opcode == TargetOpcode::G_ANYEXT) {
@@ -150,7 +191,7 @@ public:
} else {
// G_[SZ]EXT (G_IMPLICIT_DEF) -> G_CONSTANT 0 because the top
// bits will be 0 for G_ZEXT and 0/1 for the G_SEXT.
- if (isInstUnsupported({TargetOpcode::G_CONSTANT, {DstTy}}))
+ if (isConstantUnsupported(DstTy))
return false;
LLVM_DEBUG(dbgs() << ".. Combine G_[SZ]EXT(G_IMPLICIT_DEF): " << MI;);
Builder.buildConstant(DstReg, 0);
@@ -162,6 +203,16 @@ public:
return false;
}
+ static unsigned getMergeOpcode(LLT OpTy, LLT DestTy) {
+ if (OpTy.isVector() && DestTy.isVector())
+ return TargetOpcode::G_CONCAT_VECTORS;
+
+ if (OpTy.isVector() && !DestTy.isVector())
+ return TargetOpcode::G_BUILD_VECTOR;
+
+ return TargetOpcode::G_MERGE_VALUES;
+ }
+
bool tryCombineMerges(MachineInstr &MI,
SmallVectorImpl<MachineInstr *> &DeadInsts) {
@@ -169,27 +220,33 @@ public:
return false;
unsigned NumDefs = MI.getNumOperands() - 1;
+ MachineInstr *SrcDef =
+ getDefIgnoringCopies(MI.getOperand(NumDefs).getReg(), MRI);
+ if (!SrcDef)
+ return false;
- unsigned MergingOpcode;
LLT OpTy = MRI.getType(MI.getOperand(NumDefs).getReg());
LLT DestTy = MRI.getType(MI.getOperand(0).getReg());
- if (OpTy.isVector() && DestTy.isVector())
- MergingOpcode = TargetOpcode::G_CONCAT_VECTORS;
- else if (OpTy.isVector() && !DestTy.isVector())
- MergingOpcode = TargetOpcode::G_BUILD_VECTOR;
- else
- MergingOpcode = TargetOpcode::G_MERGE_VALUES;
+ MachineInstr *MergeI = SrcDef;
+ unsigned ConvertOp = 0;
- MachineInstr *MergeI =
- getOpcodeDef(MergingOpcode, MI.getOperand(NumDefs).getReg(), MRI);
+ // Handle intermediate conversions
+ unsigned SrcOp = SrcDef->getOpcode();
+ if (isArtifactCast(SrcOp)) {
+ ConvertOp = SrcOp;
+ MergeI = getDefIgnoringCopies(SrcDef->getOperand(1).getReg(), MRI);
+ }
- if (!MergeI)
+ // FIXME: Handle scalarizing concat_vectors (scalar result type with vector
+ // source)
+ unsigned MergingOpcode = getMergeOpcode(OpTy, DestTy);
+ if (!MergeI || MergeI->getOpcode() != MergingOpcode)
return false;
const unsigned NumMergeRegs = MergeI->getNumOperands() - 1;
if (NumMergeRegs < NumDefs) {
- if (NumDefs % NumMergeRegs != 0)
+ if (ConvertOp != 0 || NumDefs % NumMergeRegs != 0)
return false;
Builder.setInstr(MI);
@@ -202,7 +259,7 @@ public:
const unsigned NewNumDefs = NumDefs / NumMergeRegs;
for (unsigned Idx = 0; Idx < NumMergeRegs; ++Idx) {
- SmallVector<unsigned, 2> DstRegs;
+ SmallVector<Register, 2> DstRegs;
for (unsigned j = 0, DefIdx = Idx * NewNumDefs; j < NewNumDefs;
++j, ++DefIdx)
DstRegs.push_back(MI.getOperand(DefIdx).getReg());
@@ -211,7 +268,7 @@ public:
}
} else if (NumMergeRegs > NumDefs) {
- if (NumMergeRegs % NumDefs != 0)
+ if (ConvertOp != 0 || NumMergeRegs % NumDefs != 0)
return false;
Builder.setInstr(MI);
@@ -224,7 +281,7 @@ public:
const unsigned NumRegs = NumMergeRegs / NumDefs;
for (unsigned DefIdx = 0; DefIdx < NumDefs; ++DefIdx) {
- SmallVector<unsigned, 2> Regs;
+ SmallVector<Register, 2> Regs;
for (unsigned j = 0, Idx = NumRegs * DefIdx + 1; j < NumRegs;
++j, ++Idx)
Regs.push_back(MergeI->getOperand(Idx).getReg());
@@ -233,10 +290,22 @@ public:
}
} else {
+ LLT MergeSrcTy = MRI.getType(MergeI->getOperand(1).getReg());
+ if (ConvertOp) {
+ Builder.setInstr(MI);
+
+ for (unsigned Idx = 0; Idx < NumDefs; ++Idx) {
+ Register MergeSrc = MergeI->getOperand(Idx + 1).getReg();
+ Builder.buildInstr(ConvertOp, {MI.getOperand(Idx).getReg()},
+ {MergeSrc});
+ }
+
+ markInstAndDefDead(MI, *MergeI, DeadInsts);
+ return true;
+ }
// FIXME: is a COPY appropriate if the types mismatch? We know both
// registers are allocatable by now.
- if (MRI.getType(MI.getOperand(0).getReg()) !=
- MRI.getType(MergeI->getOperand(1).getReg()))
+ if (DestTy != MergeSrcTy)
return false;
for (unsigned Idx = 0; Idx < NumDefs; ++Idx)
@@ -248,12 +317,77 @@ public:
return true;
}
+ static bool isMergeLikeOpcode(unsigned Opc) {
+ switch (Opc) {
+ case TargetOpcode::G_MERGE_VALUES:
+ case TargetOpcode::G_BUILD_VECTOR:
+ case TargetOpcode::G_CONCAT_VECTORS:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool tryCombineExtract(MachineInstr &MI,
+ SmallVectorImpl<MachineInstr *> &DeadInsts) {
+ assert(MI.getOpcode() == TargetOpcode::G_EXTRACT);
+
+ // Try to use the source registers from a G_MERGE_VALUES
+ //
+ // %2 = G_MERGE_VALUES %0, %1
+ // %3 = G_EXTRACT %2, N
+ // =>
+ //
+ // for N < %2.getSizeInBits() / 2
+ // %3 = G_EXTRACT %0, N
+ //
+ // for N >= %2.getSizeInBits() / 2
+ // %3 = G_EXTRACT %1, (N - %0.getSizeInBits()
+
+ unsigned Src = lookThroughCopyInstrs(MI.getOperand(1).getReg());
+ MachineInstr *MergeI = MRI.getVRegDef(Src);
+ if (!MergeI || !isMergeLikeOpcode(MergeI->getOpcode()))
+ return false;
+
+ LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
+ LLT SrcTy = MRI.getType(Src);
+
+ // TODO: Do we need to check if the resulting extract is supported?
+ unsigned ExtractDstSize = DstTy.getSizeInBits();
+ unsigned Offset = MI.getOperand(2).getImm();
+ unsigned NumMergeSrcs = MergeI->getNumOperands() - 1;
+ unsigned MergeSrcSize = SrcTy.getSizeInBits() / NumMergeSrcs;
+ unsigned MergeSrcIdx = Offset / MergeSrcSize;
+
+ // Compute the offset of the last bit the extract needs.
+ unsigned EndMergeSrcIdx = (Offset + ExtractDstSize - 1) / MergeSrcSize;
+
+ // Can't handle the case where the extract spans multiple inputs.
+ if (MergeSrcIdx != EndMergeSrcIdx)
+ return false;
+
+ // TODO: We could modify MI in place in most cases.
+ Builder.setInstr(MI);
+ Builder.buildExtract(
+ MI.getOperand(0).getReg(),
+ MergeI->getOperand(MergeSrcIdx + 1).getReg(),
+ Offset - MergeSrcIdx * MergeSrcSize);
+ markInstAndDefDead(MI, *MergeI, DeadInsts);
+ return true;
+ }
+
/// Try to combine away MI.
/// Returns true if it combined away the MI.
/// Adds instructions that are dead as a result of the combine
/// into DeadInsts, which can include MI.
bool tryCombineInstruction(MachineInstr &MI,
- SmallVectorImpl<MachineInstr *> &DeadInsts) {
+ SmallVectorImpl<MachineInstr *> &DeadInsts,
+ GISelObserverWrapper &WrapperObserver) {
+ // This might be a recursive call, and we might have DeadInsts already
+ // populated. To avoid bad things happening later with multiple vreg defs
+ // etc, process the dead instructions now if any.
+ if (!DeadInsts.empty())
+ deleteMarkedDeadInsts(DeadInsts, WrapperObserver);
switch (MI.getOpcode()) {
default:
return false;
@@ -265,16 +399,35 @@ public:
return tryCombineSExt(MI, DeadInsts);
case TargetOpcode::G_UNMERGE_VALUES:
return tryCombineMerges(MI, DeadInsts);
+ case TargetOpcode::G_EXTRACT:
+ return tryCombineExtract(MI, DeadInsts);
case TargetOpcode::G_TRUNC: {
bool Changed = false;
for (auto &Use : MRI.use_instructions(MI.getOperand(0).getReg()))
- Changed |= tryCombineInstruction(Use, DeadInsts);
+ Changed |= tryCombineInstruction(Use, DeadInsts, WrapperObserver);
return Changed;
}
}
}
private:
+
+ static unsigned getArtifactSrcReg(const MachineInstr &MI) {
+ switch (MI.getOpcode()) {
+ case TargetOpcode::COPY:
+ case TargetOpcode::G_TRUNC:
+ case TargetOpcode::G_ZEXT:
+ case TargetOpcode::G_ANYEXT:
+ case TargetOpcode::G_SEXT:
+ case TargetOpcode::G_UNMERGE_VALUES:
+ return MI.getOperand(MI.getNumOperands() - 1).getReg();
+ case TargetOpcode::G_EXTRACT:
+ return MI.getOperand(1).getReg();
+ default:
+ llvm_unreachable("Not a legalization artifact happen");
+ }
+ }
+
/// Mark MI as dead. If a def of one of MI's operands, DefMI, would also be
/// dead due to MI being killed, then mark DefMI as dead too.
/// Some of the combines (extends(trunc)), try to walk through redundant
@@ -295,13 +448,15 @@ private:
// and as a result, %3, %2, %1 are dead.
MachineInstr *PrevMI = &MI;
while (PrevMI != &DefMI) {
- unsigned PrevRegSrc =
- PrevMI->getOperand(PrevMI->getNumOperands() - 1).getReg();
+ unsigned PrevRegSrc = getArtifactSrcReg(*PrevMI);
+
MachineInstr *TmpDef = MRI.getVRegDef(PrevRegSrc);
if (MRI.hasOneUse(PrevRegSrc)) {
if (TmpDef != &DefMI) {
- assert(TmpDef->getOpcode() == TargetOpcode::COPY &&
- "Expecting copy here");
+ assert((TmpDef->getOpcode() == TargetOpcode::COPY ||
+ isArtifactCast(TmpDef->getOpcode())) &&
+ "Expecting copy or artifact cast here");
+
DeadInsts.push_back(TmpDef);
}
} else
@@ -312,6 +467,22 @@ private:
DeadInsts.push_back(&DefMI);
}
+ /// Erase the dead instructions in the list and call the observer hooks.
+ /// Normally the Legalizer will deal with erasing instructions that have been
+ /// marked dead. However, for the trunc(ext(x)) cases we can end up trying to
+ /// process instructions which have been marked dead, but otherwise break the
+ /// MIR by introducing multiple vreg defs. For those cases, allow the combines
+ /// to explicitly delete the instructions before we run into trouble.
+ void deleteMarkedDeadInsts(SmallVectorImpl<MachineInstr *> &DeadInsts,
+ GISelObserverWrapper &WrapperObserver) {
+ for (auto *DeadMI : DeadInsts) {
+ LLVM_DEBUG(dbgs() << *DeadMI << "Is dead, eagerly deleting\n");
+ WrapperObserver.erasingInstr(*DeadMI);
+ DeadMI->eraseFromParentAndMarkDBGValuesForRemoval();
+ }
+ DeadInsts.clear();
+ }
+
/// Checks if the target legalizer info has specified anything about the
/// instruction, or if unsupported.
bool isInstUnsupported(const LegalityQuery &Query) const {
@@ -320,10 +491,23 @@ private:
return Step.Action == Unsupported || Step.Action == NotFound;
}
+ bool isInstLegal(const LegalityQuery &Query) const {
+ return LI.getAction(Query).Action == LegalizeActions::Legal;
+ }
+
+ bool isConstantUnsupported(LLT Ty) const {
+ if (!Ty.isVector())
+ return isInstUnsupported({TargetOpcode::G_CONSTANT, {Ty}});
+
+ LLT EltTy = Ty.getElementType();
+ return isInstUnsupported({TargetOpcode::G_CONSTANT, {EltTy}}) ||
+ isInstUnsupported({TargetOpcode::G_BUILD_VECTOR, {Ty, EltTy}});
+ }
+
/// Looks through copy instructions and returns the actual
/// source register.
- unsigned lookThroughCopyInstrs(unsigned Reg) {
- unsigned TmpReg;
+ unsigned lookThroughCopyInstrs(Register Reg) {
+ Register TmpReg;
while (mi_match(Reg, MRI, m_Copy(m_Reg(TmpReg)))) {
if (MRI.getType(TmpReg).isValid())
Reg = TmpReg;
diff --git a/include/llvm/CodeGen/GlobalISel/Legalizer.h b/include/llvm/CodeGen/GlobalISel/Legalizer.h
index 8284ab6dac65..13cf3f7e694d 100644
--- a/include/llvm/CodeGen/GlobalISel/Legalizer.h
+++ b/include/llvm/CodeGen/GlobalISel/Legalizer.h
@@ -1,9 +1,8 @@
-//== llvm/CodeGen/GlobalISel/LegalizePass.h ------------- -*- C++ -*-==//
+//== llvm/CodeGen/GlobalISel/Legalizer.h ---------------- -*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -55,6 +54,11 @@ public:
MachineFunctionProperties::Property::Legalized);
}
+ MachineFunctionProperties getClearedProperties() const override {
+ return MachineFunctionProperties()
+ .set(MachineFunctionProperties::Property::NoPHIs);
+ }
+
bool combineExtracts(MachineInstr &MI, MachineRegisterInfo &MRI,
const TargetInstrInfo &TII);
diff --git a/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index 9b4ecf9284e3..a0f21e8b19d7 100644
--- a/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -1,9 +1,8 @@
//== llvm/CodeGen/GlobalISel/LegalizerHelper.h ---------------- -*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -87,7 +86,7 @@ public:
/// Legalize a vector instruction by increasing the number of vector elements
/// involved and ignoring the added elements later.
LegalizeResult moreElementsVector(MachineInstr &MI, unsigned TypeIdx,
- LLT WideTy);
+ LLT MoreTy);
/// Expose MIRBuilder so clients can set their own RecordInsertInstruction
/// functions
@@ -105,19 +104,126 @@ private:
unsigned ExtOpcode);
/// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
+ /// Use by truncating the operand's type to \p NarrowTy using G_TRUNC, and
+ /// replacing the vreg of the operand in place.
+ void narrowScalarSrc(MachineInstr &MI, LLT NarrowTy, unsigned OpIdx);
+
+ /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
/// Def by extending the operand's type to \p WideTy and truncating it back
/// with the \p TruncOpcode, and replacing the vreg of the operand in place.
void widenScalarDst(MachineInstr &MI, LLT WideTy, unsigned OpIdx = 0,
unsigned TruncOpcode = TargetOpcode::G_TRUNC);
+ // Legalize a single operand \p OpIdx of the machine instruction \p MI as a
+ // Def by truncating the operand's type to \p NarrowTy, replacing in place and
+ // extending back with \p ExtOpcode.
+ void narrowScalarDst(MachineInstr &MI, LLT NarrowTy, unsigned OpIdx,
+ unsigned ExtOpcode);
+ /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
+ /// Def by performing it with additional vector elements and extracting the
+ /// result elements, and replacing the vreg of the operand in place.
+ void moreElementsVectorDst(MachineInstr &MI, LLT MoreTy, unsigned OpIdx);
+
+ /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
+ /// Use by producing a vector with undefined high elements, extracting the
+ /// original vector type, and replacing the vreg of the operand in place.
+ void moreElementsVectorSrc(MachineInstr &MI, LLT MoreTy, unsigned OpIdx);
+
+ LegalizeResult
+ widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
+ LegalizeResult
+ widenScalarUnmergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
+ LegalizeResult
+ widenScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
+ LegalizeResult
+ widenScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
+
/// Helper function to split a wide generic register into bitwise blocks with
/// the given Type (which implies the number of blocks needed). The generic
/// registers created are appended to Ops, starting at bit 0 of Reg.
- void extractParts(unsigned Reg, LLT Ty, int NumParts,
- SmallVectorImpl<unsigned> &VRegs);
+ void extractParts(Register Reg, LLT Ty, int NumParts,
+ SmallVectorImpl<Register> &VRegs);
+
+ /// Version which handles irregular splits.
+ bool extractParts(Register Reg, LLT RegTy, LLT MainTy,
+ LLT &LeftoverTy,
+ SmallVectorImpl<Register> &VRegs,
+ SmallVectorImpl<Register> &LeftoverVRegs);
+
+ /// Helper function to build a wide generic register \p DstReg of type \p
+ /// RegTy from smaller parts. This will produce a G_MERGE_VALUES,
+ /// G_BUILD_VECTOR, G_CONCAT_VECTORS, or sequence of G_INSERT as appropriate
+ /// for the types.
+ ///
+ /// \p PartRegs must be registers of type \p PartTy.
+ ///
+ /// If \p ResultTy does not evenly break into \p PartTy sized pieces, the
+ /// remainder must be specified with \p LeftoverRegs of type \p LeftoverTy.
+ void insertParts(Register DstReg, LLT ResultTy,
+ LLT PartTy, ArrayRef<Register> PartRegs,
+ LLT LeftoverTy = LLT(), ArrayRef<Register> LeftoverRegs = {});
+
+ /// Perform generic multiplication of values held in multiple registers.
+ /// Generated instructions use only types NarrowTy and i1.
+ /// Destination can be same or two times size of the source.
+ void multiplyRegisters(SmallVectorImpl<Register> &DstRegs,
+ ArrayRef<Register> Src1Regs,
+ ArrayRef<Register> Src2Regs, LLT NarrowTy);
+
+public:
+ LegalizeResult fewerElementsVectorImplicitDef(MachineInstr &MI,
+ unsigned TypeIdx, LLT NarrowTy);
+
+ /// Legalize a simple vector instruction where all operands are the same type
+ /// by splitting into multiple components.
+ LegalizeResult fewerElementsVectorBasic(MachineInstr &MI, unsigned TypeIdx,
+ LLT NarrowTy);
+
+ /// Legalize a instruction with a vector type where each operand may have a
+ /// different element type. All type indexes must have the same number of
+ /// elements.
+ LegalizeResult fewerElementsVectorMultiEltType(MachineInstr &MI,
+ unsigned TypeIdx, LLT NarrowTy);
+
+ LegalizeResult fewerElementsVectorCasts(MachineInstr &MI, unsigned TypeIdx,
+ LLT NarrowTy);
+
+ LegalizeResult
+ fewerElementsVectorCmp(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
+
+ LegalizeResult
+ fewerElementsVectorSelect(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
+
+ LegalizeResult fewerElementsVectorPhi(MachineInstr &MI,
+ unsigned TypeIdx, LLT NarrowTy);
+
+ LegalizeResult moreElementsVectorPhi(MachineInstr &MI, unsigned TypeIdx,
+ LLT MoreTy);
+
+ LegalizeResult
+ reduceLoadStoreWidth(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
+
+ LegalizeResult narrowScalarShiftByConstant(MachineInstr &MI, const APInt &Amt,
+ LLT HalfTy, LLT ShiftAmtTy);
+
+ LegalizeResult narrowScalarShift(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+ LegalizeResult narrowScalarMul(MachineInstr &MI, LLT Ty);
+ LegalizeResult narrowScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+ LegalizeResult narrowScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+
+ LegalizeResult narrowScalarBasic(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+ LegalizeResult narrowScalarSelect(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
LegalizeResult lowerBitCount(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+ LegalizeResult lowerU64ToF32BitOps(MachineInstr &MI);
+ LegalizeResult lowerUITOFP(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+ LegalizeResult lowerSITOFP(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+ LegalizeResult lowerMinMax(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+ LegalizeResult lowerFCopySign(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+ LegalizeResult lowerFMinNumMaxNum(MachineInstr &MI);
+
+private:
MachineRegisterInfo &MRI;
const LegalizerInfo &LI;
/// To keep track of changes made by the LegalizerHelper.
diff --git a/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h b/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
index 13776dd3e87d..513c98f2d23f 100644
--- a/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
+++ b/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/GlobalISel/LegalizerInfo.h ------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -93,6 +92,7 @@ enum LegalizeAction : std::uint8_t {
UseLegacyRules,
};
} // end namespace LegalizeActions
+raw_ostream &operator<<(raw_ostream &OS, LegalizeActions::LegalizeAction Action);
using LegalizeActions::LegalizeAction;
@@ -123,6 +123,7 @@ struct LegalityQuery {
struct MemDesc {
uint64_t SizeInBits;
+ uint64_t AlignInBits;
AtomicOrdering Ordering;
};
@@ -165,13 +166,23 @@ using LegalizeMutation =
std::function<std::pair<unsigned, LLT>(const LegalityQuery &)>;
namespace LegalityPredicates {
-struct TypePairAndMemSize {
+struct TypePairAndMemDesc {
LLT Type0;
LLT Type1;
uint64_t MemSize;
+ uint64_t Align;
+
+ bool operator==(const TypePairAndMemDesc &Other) const {
+ return Type0 == Other.Type0 && Type1 == Other.Type1 &&
+ Align == Other.Align &&
+ MemSize == Other.MemSize;
+ }
- bool operator==(const TypePairAndMemSize &Other) const {
+ /// \returns true if this memory access is legal with for the acecss described
+ /// by \p Other (The alignment is sufficient for the size and result type).
+ bool isCompatible(const TypePairAndMemDesc &Other) const {
return Type0 == Other.Type0 && Type1 == Other.Type1 &&
+ Align >= Other.Align &&
MemSize == Other.MemSize;
}
};
@@ -200,20 +211,45 @@ typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1,
std::initializer_list<std::pair<LLT, LLT>> TypesInit);
/// True iff the given types for the given pair of type indexes is one of the
/// specified type pairs.
-LegalityPredicate typePairAndMemSizeInSet(
+LegalityPredicate typePairAndMemDescInSet(
unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx,
- std::initializer_list<TypePairAndMemSize> TypesAndMemSizeInit);
+ std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit);
/// True iff the specified type index is a scalar.
LegalityPredicate isScalar(unsigned TypeIdx);
+/// True iff the specified type index is a vector.
+LegalityPredicate isVector(unsigned TypeIdx);
+/// True iff the specified type index is a pointer (with any address space).
+LegalityPredicate isPointer(unsigned TypeIdx);
+/// True iff the specified type index is a pointer with the specified address
+/// space.
+LegalityPredicate isPointer(unsigned TypeIdx, unsigned AddrSpace);
+
/// True iff the specified type index is a scalar that's narrower than the given
/// size.
LegalityPredicate narrowerThan(unsigned TypeIdx, unsigned Size);
+
/// True iff the specified type index is a scalar that's wider than the given
/// size.
LegalityPredicate widerThan(unsigned TypeIdx, unsigned Size);
+
+/// True iff the specified type index is a scalar or vector with an element type
+/// that's narrower than the given size.
+LegalityPredicate scalarOrEltNarrowerThan(unsigned TypeIdx, unsigned Size);
+
+/// True iff the specified type index is a scalar or a vector with an element
+/// type that's wider than the given size.
+LegalityPredicate scalarOrEltWiderThan(unsigned TypeIdx, unsigned Size);
+
/// True iff the specified type index is a scalar whose size is not a power of
/// 2.
LegalityPredicate sizeNotPow2(unsigned TypeIdx);
+
+/// True iff the specified type index is a scalar or vector whose element size
+/// is not a power of 2.
+LegalityPredicate scalarOrEltSizeNotPow2(unsigned TypeIdx);
+
+/// True iff the specified type indices are both the same bit size.
+LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1);
/// True iff the specified MMO index has a size that is not a power of 2
LegalityPredicate memSizeInBytesNotPow2(unsigned MMOIdx);
/// True iff the specified type index is a vector whose element count is not a
@@ -228,13 +264,25 @@ LegalityPredicate atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx,
namespace LegalizeMutations {
/// Select this specific type for the given type index.
LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty);
+
/// Keep the same type as the given type index.
LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx);
-/// Widen the type for the given type index to the next power of 2.
-LegalizeMutation widenScalarToNextPow2(unsigned TypeIdx, unsigned Min = 0);
+
+/// Keep the same scalar or element type as the given type index.
+LegalizeMutation changeElementTo(unsigned TypeIdx, unsigned FromTypeIdx);
+
+/// Keep the same scalar or element type as the given type.
+LegalizeMutation changeElementTo(unsigned TypeIdx, LLT Ty);
+
+/// Widen the scalar type or vector element type for the given type index to the
+/// next power of 2.
+LegalizeMutation widenScalarOrEltToNextPow2(unsigned TypeIdx, unsigned Min = 0);
+
/// Add more elements to the type for the given type index to the next power of
/// 2.
LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx, unsigned Min = 0);
+/// Break up the vector type for the given type index into the element type.
+LegalizeMutation scalarize(unsigned TypeIdx);
} // end namespace LegalizeMutations
/// A single rule in a legalizer info ruleset.
@@ -419,13 +467,13 @@ public:
return actionFor(LegalizeAction::Legal, Types);
}
/// The instruction is legal when type indexes 0 and 1 along with the memory
- /// size is any type and size tuple in the given list.
- LegalizeRuleSet &legalForTypesWithMemSize(
- std::initializer_list<LegalityPredicates::TypePairAndMemSize>
- TypesAndMemSize) {
+ /// size and minimum alignment is any type and size tuple in the given list.
+ LegalizeRuleSet &legalForTypesWithMemDesc(
+ std::initializer_list<LegalityPredicates::TypePairAndMemDesc>
+ TypesAndMemDesc) {
return actionIf(LegalizeAction::Legal,
- LegalityPredicates::typePairAndMemSizeInSet(
- typeIdx(0), typeIdx(1), /*MMOIdx*/ 0, TypesAndMemSize));
+ LegalityPredicates::typePairAndMemDescInSet(
+ typeIdx(0), typeIdx(1), /*MMOIdx*/ 0, TypesAndMemDesc));
}
/// The instruction is legal when type indexes 0 and 1 are both in the given
/// list. That is, the type pair is in the cartesian product of the list.
@@ -438,6 +486,20 @@ public:
std::initializer_list<LLT> Types1) {
return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1);
}
+ /// The instruction is legal when type indexes 0, 1, and 2 are both their
+ /// respective lists.
+ LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
+ std::initializer_list<LLT> Types1,
+ std::initializer_list<LLT> Types2) {
+ return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1,
+ Types2);
+ }
+
+ LegalizeRuleSet &alwaysLegal() {
+ using namespace LegalizeMutations;
+ markAllTypeIdxsAsCovered();
+ return actionIf(LegalizeAction::Legal, always);
+ }
/// The instruction is lowered.
LegalizeRuleSet &lower() {
@@ -588,6 +650,13 @@ public:
LegalizeRuleSet &customFor(std::initializer_list<LLT> Types) {
return actionFor(LegalizeAction::Custom, Types);
}
+
+ /// The instruction is custom when type indexes 0 and 1 is any type pair in the
+ /// given list.
+ LegalizeRuleSet &customFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
+ return actionFor(LegalizeAction::Custom, Types);
+ }
+
LegalizeRuleSet &customForCartesianProduct(std::initializer_list<LLT> Types) {
return actionForCartesianProduct(LegalizeAction::Custom, Types);
}
@@ -597,13 +666,29 @@ public:
return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
}
+ /// Unconditionally custom lower.
+ LegalizeRuleSet &custom() {
+ return customIf(always);
+ }
+
/// Widen the scalar to the next power of two that is at least MinSize.
/// No effect if the type is not a scalar or is a power of two.
LegalizeRuleSet &widenScalarToNextPow2(unsigned TypeIdx,
unsigned MinSize = 0) {
using namespace LegalityPredicates;
- return actionIf(LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
- LegalizeMutations::widenScalarToNextPow2(TypeIdx, MinSize));
+ return actionIf(
+ LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
+ LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize));
+ }
+
+ /// Widen the scalar or vector element type to the next power of two that is
+ /// at least MinSize. No effect if the scalar size is a power of two.
+ LegalizeRuleSet &widenScalarOrEltToNextPow2(unsigned TypeIdx,
+ unsigned MinSize = 0) {
+ using namespace LegalityPredicates;
+ return actionIf(
+ LegalizeAction::WidenScalar, scalarOrEltSizeNotPow2(typeIdx(TypeIdx)),
+ LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize));
}
LegalizeRuleSet &narrowScalar(unsigned TypeIdx, LegalizeMutation Mutation) {
@@ -612,6 +697,32 @@ public:
Mutation);
}
+ LegalizeRuleSet &scalarize(unsigned TypeIdx) {
+ using namespace LegalityPredicates;
+ return actionIf(LegalizeAction::FewerElements, isVector(typeIdx(TypeIdx)),
+ LegalizeMutations::scalarize(TypeIdx));
+ }
+
+ /// Ensure the scalar or element is at least as wide as Ty.
+ LegalizeRuleSet &minScalarOrElt(unsigned TypeIdx, const LLT &Ty) {
+ using namespace LegalityPredicates;
+ using namespace LegalizeMutations;
+ return actionIf(LegalizeAction::WidenScalar,
+ scalarOrEltNarrowerThan(TypeIdx, Ty.getScalarSizeInBits()),
+ changeElementTo(typeIdx(TypeIdx), Ty));
+ }
+
+ /// Ensure the scalar or element is at least as wide as Ty.
+ LegalizeRuleSet &minScalarOrEltIf(LegalityPredicate Predicate,
+ unsigned TypeIdx, const LLT &Ty) {
+ using namespace LegalityPredicates;
+ using namespace LegalizeMutations;
+ return actionIf(LegalizeAction::WidenScalar,
+ all(Predicate, scalarOrEltNarrowerThan(
+ TypeIdx, Ty.getScalarSizeInBits())),
+ changeElementTo(typeIdx(TypeIdx), Ty));
+ }
+
/// Ensure the scalar is at least as wide as Ty.
LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT &Ty) {
using namespace LegalityPredicates;
@@ -622,6 +733,15 @@ public:
}
/// Ensure the scalar is at most as wide as Ty.
+ LegalizeRuleSet &maxScalarOrElt(unsigned TypeIdx, const LLT &Ty) {
+ using namespace LegalityPredicates;
+ using namespace LegalizeMutations;
+ return actionIf(LegalizeAction::NarrowScalar,
+ scalarOrEltWiderThan(TypeIdx, Ty.getScalarSizeInBits()),
+ changeElementTo(typeIdx(TypeIdx), Ty));
+ }
+
+ /// Ensure the scalar is at most as wide as Ty.
LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT &Ty) {
using namespace LegalityPredicates;
using namespace LegalizeMutations;
@@ -637,12 +757,12 @@ public:
const LLT &Ty) {
using namespace LegalityPredicates;
using namespace LegalizeMutations;
- return actionIf(LegalizeAction::NarrowScalar,
- [=](const LegalityQuery &Query) {
- return widerThan(TypeIdx, Ty.getSizeInBits()) &&
- Predicate(Query);
- },
- changeTo(typeIdx(TypeIdx), Ty));
+ return actionIf(
+ LegalizeAction::NarrowScalar,
+ [=](const LegalityQuery &Query) {
+ return widerThan(TypeIdx, Ty.getSizeInBits()) && Predicate(Query);
+ },
+ changeElementTo(typeIdx(TypeIdx), Ty));
}
/// Limit the range of scalar sizes to MinTy and MaxTy.
@@ -652,6 +772,12 @@ public:
return minScalar(TypeIdx, MinTy).maxScalar(TypeIdx, MaxTy);
}
+ /// Limit the range of scalar sizes to MinTy and MaxTy.
+ LegalizeRuleSet &clampScalarOrElt(unsigned TypeIdx, const LLT &MinTy,
+ const LLT &MaxTy) {
+ return minScalarOrElt(TypeIdx, MinTy).maxScalarOrElt(TypeIdx, MaxTy);
+ }
+
/// Widen the scalar to match the size of another.
LegalizeRuleSet &minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx) {
typeIdx(TypeIdx);
@@ -661,8 +787,25 @@ public:
Query.Types[TypeIdx].getSizeInBits();
},
[=](const LegalityQuery &Query) {
+ LLT T = Query.Types[LargeTypeIdx];
return std::make_pair(TypeIdx,
- Query.Types[LargeTypeIdx].getElementType());
+ T.isVector() ? T.getElementType() : T);
+ });
+ }
+
+ /// Conditionally widen the scalar or elt to match the size of another.
+ LegalizeRuleSet &minScalarEltSameAsIf(LegalityPredicate Predicate,
+ unsigned TypeIdx, unsigned LargeTypeIdx) {
+ typeIdx(TypeIdx);
+ return widenScalarIf(
+ [=](const LegalityQuery &Query) {
+ return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
+ Query.Types[TypeIdx].getScalarSizeInBits() &&
+ Predicate(Query);
+ },
+ [=](const LegalityQuery &Query) {
+ LLT T = Query.Types[LargeTypeIdx];
+ return std::make_pair(TypeIdx, T);
});
}
@@ -691,7 +834,7 @@ public:
[=](const LegalityQuery &Query) {
LLT VecTy = Query.Types[TypeIdx];
return std::make_pair(
- TypeIdx, LLT::vector(MinElements, VecTy.getScalarSizeInBits()));
+ TypeIdx, LLT::vector(MinElements, VecTy.getElementType()));
});
}
/// Limit the number of elements in EltTy vectors to at most MaxElements.
@@ -708,10 +851,8 @@ public:
},
[=](const LegalityQuery &Query) {
LLT VecTy = Query.Types[TypeIdx];
- if (MaxElements == 1)
- return std::make_pair(TypeIdx, VecTy.getElementType());
- return std::make_pair(
- TypeIdx, LLT::vector(MaxElements, VecTy.getScalarSizeInBits()));
+ LLT NewTy = LLT::scalarOrVector(MaxElements, VecTy.getElementType());
+ return std::make_pair(TypeIdx, NewTy);
});
}
/// Limit the number of elements for the given vectors to at least MinTy's
@@ -962,12 +1103,22 @@ public:
LegalizeActionStep getAction(const MachineInstr &MI,
const MachineRegisterInfo &MRI) const;
+ bool isLegal(const LegalityQuery &Query) const {
+ return getAction(Query).Action == LegalizeAction::Legal;
+ }
bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;
+ bool isLegalOrCustom(const MachineInstr &MI,
+ const MachineRegisterInfo &MRI) const;
virtual bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI,
MachineIRBuilder &MIRBuilder,
GISelChangeObserver &Observer) const;
+ /// Return true if MI is either legal or has been legalized and false
+ /// if not legal.
+ virtual bool legalizeIntrinsic(MachineInstr &MI, MachineRegisterInfo &MRI,
+ MachineIRBuilder &MIRBuilder) const;
+
private:
/// Determine what action should be taken to legalize the given generic
/// instruction opcode, type-index and type. Requires computeTables to have
diff --git a/include/llvm/CodeGen/GlobalISel/Localizer.h b/include/llvm/CodeGen/GlobalISel/Localizer.h
index 1e2d4763e5e1..06de5800b8b7 100644
--- a/include/llvm/CodeGen/GlobalISel/Localizer.h
+++ b/include/llvm/CodeGen/GlobalISel/Localizer.h
@@ -1,9 +1,8 @@
//== llvm/CodeGen/GlobalISel/Localizer.h - Localizer -------------*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -22,12 +21,14 @@
#ifndef LLVM_CODEGEN_GLOBALISEL_LOCALIZER_H
#define LLVM_CODEGEN_GLOBALISEL_LOCALIZER_H
+#include "llvm/ADT/SetVector.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
namespace llvm {
// Forward declarations.
class MachineRegisterInfo;
+class TargetTransformInfo;
/// This pass implements the localization mechanism described at the
/// top of this file. One specificity of the implementation is that
@@ -44,9 +45,11 @@ private:
/// MRI contains all the register class/bank information that this
/// pass uses and updates.
MachineRegisterInfo *MRI;
+ /// TTI used for getting remat costs for instructions.
+ TargetTransformInfo *TTI;
/// Check whether or not \p MI needs to be moved close to its uses.
- static bool shouldLocalize(const MachineInstr &MI);
+ bool shouldLocalize(const MachineInstr &MI);
/// Check if \p MOUse is used in the same basic block as \p Def.
/// If the use is in the same block, we say it is local.
@@ -58,6 +61,15 @@ private:
/// Initialize the field members using \p MF.
void init(MachineFunction &MF);
+ typedef SmallSetVector<MachineInstr *, 32> LocalizedSetVecT;
+
+ /// Do inter-block localization from the entry block.
+ bool localizeInterBlock(MachineFunction &MF,
+ LocalizedSetVecT &LocalizedInstrs);
+
+ /// Do intra-block localization of already localized instructions.
+ bool localizeIntraBlock(LocalizedSetVecT &LocalizedInstrs);
+
public:
Localizer();
diff --git a/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
index f77f9a8df7ee..13eddd9539fa 100644
--- a/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
+++ b/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
@@ -1,9 +1,8 @@
-//== ----- llvm/CodeGen/GlobalISel/MIPatternMatch.h --------------------- == //
+//==------ llvm/CodeGen/GlobalISel/MIPatternMatch.h -------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -31,8 +30,7 @@ template <typename SubPatternT> struct OneUse_match {
SubPatternT SubPat;
OneUse_match(const SubPatternT &SP) : SubPat(SP) {}
- template <typename OpTy>
- bool match(const MachineRegisterInfo &MRI, unsigned Reg) {
+ bool match(MachineRegisterInfo &MRI, unsigned Reg) {
return MRI.hasOneUse(Reg) && SubPat.match(MRI, Reg);
}
};
@@ -162,7 +160,7 @@ template <typename Class> struct bind_ty {
}
};
-inline bind_ty<unsigned> m_Reg(unsigned &R) { return R; }
+inline bind_ty<Register> m_Reg(Register &R) { return R; }
inline bind_ty<MachineInstr *> m_MInstr(MachineInstr *&MI) { return MI; }
inline bind_ty<LLT> m_Type(LLT &Ty) { return Ty; }
diff --git a/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index 37de8f030410..10d712176b1b 100644
--- a/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/GlobalISel/MachineIRBuilder.h - MIBuilder --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
@@ -60,13 +59,15 @@ struct MachineIRBuilderState {
class DstOp {
union {
LLT LLTTy;
- unsigned Reg;
+ Register Reg;
const TargetRegisterClass *RC;
};
public:
enum class DstType { Ty_LLT, Ty_Reg, Ty_RC };
DstOp(unsigned R) : Reg(R), Ty(DstType::Ty_Reg) {}
+ DstOp(Register R) : Reg(R), Ty(DstType::Ty_Reg) {}
+ DstOp(const MachineOperand &Op) : Reg(Op.getReg()), Ty(DstType::Ty_Reg) {}
DstOp(const LLT &T) : LLTTy(T), Ty(DstType::Ty_LLT) {}
DstOp(const TargetRegisterClass *TRC) : RC(TRC), Ty(DstType::Ty_RC) {}
@@ -96,7 +97,7 @@ public:
llvm_unreachable("Unrecognised DstOp::DstType enum");
}
- unsigned getReg() const {
+ Register getReg() const {
assert(Ty == DstType::Ty_Reg && "Not a register");
return Reg;
}
@@ -119,13 +120,14 @@ private:
class SrcOp {
union {
MachineInstrBuilder SrcMIB;
- unsigned Reg;
+ Register Reg;
CmpInst::Predicate Pred;
};
public:
enum class SrcType { Ty_Reg, Ty_MIB, Ty_Predicate };
- SrcOp(unsigned R) : Reg(R), Ty(SrcType::Ty_Reg) {}
+ SrcOp(Register R) : Reg(R), Ty(SrcType::Ty_Reg) {}
+ SrcOp(const MachineOperand &Op) : Reg(Op.getReg()), Ty(SrcType::Ty_Reg) {}
SrcOp(const MachineInstrBuilder &MIB) : SrcMIB(MIB), Ty(SrcType::Ty_MIB) {}
SrcOp(const CmpInst::Predicate P) : Pred(P), Ty(SrcType::Ty_Predicate) {}
@@ -155,7 +157,7 @@ public:
llvm_unreachable("Unrecognised SrcOp::SrcType enum");
}
- unsigned getReg() const {
+ Register getReg() const {
switch (Ty) {
case SrcType::Ty_Predicate:
llvm_unreachable("Not a register operand");
@@ -202,6 +204,7 @@ protected:
void validateTruncExt(const LLT &Dst, const LLT &Src, bool IsExtend);
void validateBinaryOp(const LLT &Res, const LLT &Op0, const LLT &Op1);
+ void validateShiftOp(const LLT &Res, const LLT &Op0, const LLT &Op1);
void validateSelectOp(const LLT &ResTy, const LLT &TstTy, const LLT &Op0Ty,
const LLT &Op1Ty);
@@ -230,6 +233,15 @@ public:
return *State.MF;
}
+ const MachineFunction &getMF() const {
+ assert(State.MF && "MachineFunction is not set");
+ return *State.MF;
+ }
+
+ const DataLayout &getDataLayout() const {
+ return getMF().getFunction().getParent()->getDataLayout();
+ }
+
/// Getter for DebugLoc
const DebugLoc &getDL() { return State.DL; }
@@ -310,13 +322,13 @@ public:
/// Build and insert a DBG_VALUE instruction expressing the fact that the
/// associated \p Variable lives in \p Reg (suitably modified by \p Expr).
- MachineInstrBuilder buildDirectDbgValue(unsigned Reg, const MDNode *Variable,
+ MachineInstrBuilder buildDirectDbgValue(Register Reg, const MDNode *Variable,
const MDNode *Expr);
/// Build and insert a DBG_VALUE instruction expressing the fact that the
/// associated \p Variable lives in memory at \p Reg (suitably modified by \p
/// Expr).
- MachineInstrBuilder buildIndirectDbgValue(unsigned Reg,
+ MachineInstrBuilder buildIndirectDbgValue(Register Reg,
const MDNode *Variable,
const MDNode *Expr);
@@ -345,7 +357,7 @@ public:
/// \pre \p Res must be a generic virtual register with pointer type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildFrameIndex(unsigned Res, int Idx);
+ MachineInstrBuilder buildFrameIndex(const DstOp &Res, int Idx);
/// Build and insert \p Res = G_GLOBAL_VALUE \p GV
///
@@ -357,8 +369,7 @@ public:
/// in the same address space as \p GV.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildGlobalValue(unsigned Res, const GlobalValue *GV);
-
+ MachineInstrBuilder buildGlobalValue(const DstOp &Res, const GlobalValue *GV);
/// Build and insert \p Res = G_GEP \p Op0, \p Op1
///
@@ -371,8 +382,8 @@ public:
/// \pre \p Op1 must be a generic virtual register with scalar type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildGEP(unsigned Res, unsigned Op0,
- unsigned Op1);
+ MachineInstrBuilder buildGEP(const DstOp &Res, const SrcOp &Op0,
+ const SrcOp &Op1);
/// Materialize and insert \p Res = G_GEP \p Op0, (G_CONSTANT \p Value)
///
@@ -390,7 +401,7 @@ public:
/// type as \p Op0 or \p Op0 itself.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- Optional<MachineInstrBuilder> materializeGEP(unsigned &Res, unsigned Op0,
+ Optional<MachineInstrBuilder> materializeGEP(Register &Res, Register Op0,
const LLT &ValueTy,
uint64_t Value);
@@ -407,9 +418,24 @@ public:
/// be cleared in \p Op0.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildPtrMask(unsigned Res, unsigned Op0,
+ MachineInstrBuilder buildPtrMask(const DstOp &Res, const SrcOp &Op0,
uint32_t NumBits);
+ /// Build and insert \p Res, \p CarryOut = G_UADDO \p Op0, \p Op1
+ ///
+ /// G_UADDO sets \p Res to \p Op0 + \p Op1 (truncated to the bit width) and
+ /// sets \p CarryOut to 1 if the result overflowed in unsigned arithmetic.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers with the
+ /// same scalar type.
+ ////\pre \p CarryOut must be generic virtual register with scalar type
+ ///(typically s1)
+ ///
+ /// \return The newly created instruction.
+ MachineInstrBuilder buildUAddo(const DstOp &Res, const DstOp &CarryOut,
+ const SrcOp &Op0, const SrcOp &Op1);
+
/// Build and insert \p Res, \p CarryOut = G_UADDE \p Op0,
/// \p Op1, \p CarryIn
///
@@ -458,6 +484,25 @@ public:
/// \return The newly created instruction.
MachineInstrBuilder buildSExt(const DstOp &Res, const SrcOp &Op);
+ /// Build and insert a G_PTRTOINT instruction.
+ MachineInstrBuilder buildPtrToInt(const DstOp &Dst, const SrcOp &Src) {
+ return buildInstr(TargetOpcode::G_PTRTOINT, {Dst}, {Src});
+ }
+
+ /// Build and insert \p Dst = G_BITCAST \p Src
+ MachineInstrBuilder buildBitcast(const DstOp &Dst, const SrcOp &Src) {
+ return buildInstr(TargetOpcode::G_BITCAST, {Dst}, {Src});
+ }
+
+ /// \return The opcode of the extension the target wants to use for boolean
+ /// values.
+ unsigned getBoolExtOp(bool IsVec, bool IsFP) const;
+
+ // Build and insert \p Res = G_ANYEXT \p Op, \p Res = G_SEXT \p Op, or \p Res
+ // = G_ZEXT \p Op depending on how the target wants to extend boolean values.
+ MachineInstrBuilder buildBoolExt(const DstOp &Res, const SrcOp &Op,
+ bool IsFP);
+
/// Build and insert \p Res = G_ZEXT \p Op
///
/// G_ZEXT produces a register of the specified width, with bits 0 to
@@ -538,7 +583,7 @@ public:
/// depend on bit 0 (for now).
///
/// \return The newly created instruction.
- MachineInstrBuilder buildBrCond(unsigned Tst, MachineBasicBlock &Dest);
+ MachineInstrBuilder buildBrCond(Register Tst, MachineBasicBlock &Dest);
/// Build and insert G_BRINDIRECT \p Tgt
///
@@ -548,7 +593,21 @@ public:
/// \pre \p Tgt must be a generic virtual register with pointer type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildBrIndirect(unsigned Tgt);
+ MachineInstrBuilder buildBrIndirect(Register Tgt);
+
+ /// Build and insert G_BRJT \p TablePtr, \p JTI, \p IndexReg
+ ///
+ /// G_BRJT is a jump table branch using a table base pointer \p TablePtr,
+ /// jump table index \p JTI and index \p IndexReg
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ /// \pre \p TablePtr must be a generic virtual register with pointer type.
+ /// \pre \p JTI must be be a jump table index.
+ /// \pre \p IndexReg must be a generic virtual register with pointer type.
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildBrJT(Register TablePtr, unsigned JTI,
+ Register IndexReg);
/// Build and insert \p Res = G_CONSTANT \p Val
///
@@ -572,6 +631,7 @@ public:
///
/// \return The newly created instruction.
MachineInstrBuilder buildConstant(const DstOp &Res, int64_t Val);
+ MachineInstrBuilder buildConstant(const DstOp &Res, const APInt &Val);
/// Build and insert \p Res = G_FCONSTANT \p Val
///
@@ -586,6 +646,7 @@ public:
const ConstantFP &Val);
MachineInstrBuilder buildFConstant(const DstOp &Res, double Val);
+ MachineInstrBuilder buildFConstant(const DstOp &Res, const APFloat &Val);
/// Build and insert \p Res = COPY Op
///
@@ -605,7 +666,7 @@ public:
/// \pre \p Addr must be a generic virtual register with pointer type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildLoad(unsigned Res, unsigned Addr,
+ MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr,
MachineMemOperand &MMO);
/// Build and insert `Res = <opcode> Addr, MMO`.
@@ -617,8 +678,8 @@ public:
/// \pre \p Addr must be a generic virtual register with pointer type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildLoadInstr(unsigned Opcode, unsigned Res,
- unsigned Addr, MachineMemOperand &MMO);
+ MachineInstrBuilder buildLoadInstr(unsigned Opcode, const DstOp &Res,
+ const SrcOp &Addr, MachineMemOperand &MMO);
/// Build and insert `G_STORE Val, Addr, MMO`.
///
@@ -629,7 +690,7 @@ public:
/// \pre \p Addr must be a generic virtual register with pointer type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildStore(unsigned Val, unsigned Addr,
+ MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr,
MachineMemOperand &MMO);
/// Build and insert `Res0, ... = G_EXTRACT Src, Idx0`.
@@ -638,7 +699,7 @@ public:
/// \pre \p Res and \p Src must be generic virtual registers.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildExtract(unsigned Res, unsigned Src, uint64_t Index);
+ MachineInstrBuilder buildExtract(const DstOp &Res, const SrcOp &Src, uint64_t Index);
/// Build and insert \p Res = IMPLICIT_DEF.
MachineInstrBuilder buildUndef(const DstOp &Res);
@@ -656,7 +717,7 @@ public:
/// \pre The bits defined by each Op (derived from index and scalar size) must
/// not overlap.
/// \pre \p Indices must be in ascending order of bit position.
- void buildSequence(unsigned Res, ArrayRef<unsigned> Ops,
+ void buildSequence(Register Res, ArrayRef<Register> Ops,
ArrayRef<uint64_t> Indices);
/// Build and insert \p Res = G_MERGE_VALUES \p Op0, ...
@@ -670,7 +731,7 @@ public:
/// \pre The type of all \p Ops registers must be identical.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildMerge(const DstOp &Res, ArrayRef<unsigned> Ops);
+ MachineInstrBuilder buildMerge(const DstOp &Res, ArrayRef<Register> Ops);
/// Build and insert \p Res0, ... = G_UNMERGE_VALUES \p Op
///
@@ -683,7 +744,10 @@ public:
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildUnmerge(ArrayRef<LLT> Res, const SrcOp &Op);
- MachineInstrBuilder buildUnmerge(ArrayRef<unsigned> Res, const SrcOp &Op);
+ MachineInstrBuilder buildUnmerge(ArrayRef<Register> Res, const SrcOp &Op);
+
+ /// Build and insert an unmerge of \p Res sized pieces to cover \p Op
+ MachineInstrBuilder buildUnmerge(LLT Res, const SrcOp &Op);
/// Build and insert \p Res = G_BUILD_VECTOR \p Op0, ...
///
@@ -695,7 +759,12 @@ public:
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildBuildVector(const DstOp &Res,
- ArrayRef<unsigned> Ops);
+ ArrayRef<Register> Ops);
+
+ /// Build and insert \p Res = G_BUILD_VECTOR with \p Src replicated to fill
+ /// the number of elements
+ MachineInstrBuilder buildSplatVector(const DstOp &Res,
+ const SrcOp &Src);
/// Build and insert \p Res = G_BUILD_VECTOR_TRUNC \p Op0, ...
///
@@ -711,7 +780,7 @@ public:
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildBuildVectorTrunc(const DstOp &Res,
- ArrayRef<unsigned> Ops);
+ ArrayRef<Register> Ops);
/// Build and insert \p Res = G_CONCAT_VECTORS \p Op0, ...
///
@@ -725,10 +794,10 @@ public:
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildConcatVectors(const DstOp &Res,
- ArrayRef<unsigned> Ops);
+ ArrayRef<Register> Ops);
- MachineInstrBuilder buildInsert(unsigned Res, unsigned Src,
- unsigned Op, unsigned Index);
+ MachineInstrBuilder buildInsert(Register Res, Register Src,
+ Register Op, unsigned Index);
/// Build and insert either a G_INTRINSIC (if \p HasSideEffects is false) or
/// G_INTRINSIC_W_SIDE_EFFECTS instruction. Its first operand will be the
@@ -740,7 +809,9 @@ public:
/// \pre setBasicBlock or setMI must have been called.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildIntrinsic(Intrinsic::ID ID, unsigned Res,
+ MachineInstrBuilder buildIntrinsic(Intrinsic::ID ID, ArrayRef<Register> Res,
+ bool HasSideEffects);
+ MachineInstrBuilder buildIntrinsic(Intrinsic::ID ID, ArrayRef<DstOp> Res,
bool HasSideEffects);
/// Build and insert \p Res = G_FPTRUNC \p Op
@@ -855,8 +926,8 @@ public:
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder
- buildAtomicCmpXchgWithSuccess(unsigned OldValRes, unsigned SuccessRes,
- unsigned Addr, unsigned CmpVal, unsigned NewVal,
+ buildAtomicCmpXchgWithSuccess(Register OldValRes, Register SuccessRes,
+ Register Addr, Register CmpVal, Register NewVal,
MachineMemOperand &MMO);
/// Build and insert `OldValRes<def> = G_ATOMIC_CMPXCHG Addr, CmpVal, NewVal,
@@ -873,8 +944,8 @@ public:
/// registers of the same type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildAtomicCmpXchg(unsigned OldValRes, unsigned Addr,
- unsigned CmpVal, unsigned NewVal,
+ MachineInstrBuilder buildAtomicCmpXchg(Register OldValRes, Register Addr,
+ Register CmpVal, Register NewVal,
MachineMemOperand &MMO);
/// Build and insert `OldValRes<def> = G_ATOMICRMW_<Opcode> Addr, Val, MMO`.
@@ -890,8 +961,8 @@ public:
/// same type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildAtomicRMW(unsigned Opcode, unsigned OldValRes,
- unsigned Addr, unsigned Val,
+ MachineInstrBuilder buildAtomicRMW(unsigned Opcode, Register OldValRes,
+ Register Addr, Register Val,
MachineMemOperand &MMO);
/// Build and insert `OldValRes<def> = G_ATOMICRMW_XCHG Addr, Val, MMO`.
@@ -906,8 +977,8 @@ public:
/// same type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildAtomicRMWXchg(unsigned OldValRes, unsigned Addr,
- unsigned Val, MachineMemOperand &MMO);
+ MachineInstrBuilder buildAtomicRMWXchg(Register OldValRes, Register Addr,
+ Register Val, MachineMemOperand &MMO);
/// Build and insert `OldValRes<def> = G_ATOMICRMW_ADD Addr, Val, MMO`.
///
@@ -921,8 +992,8 @@ public:
/// same type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildAtomicRMWAdd(unsigned OldValRes, unsigned Addr,
- unsigned Val, MachineMemOperand &MMO);
+ MachineInstrBuilder buildAtomicRMWAdd(Register OldValRes, Register Addr,
+ Register Val, MachineMemOperand &MMO);
/// Build and insert `OldValRes<def> = G_ATOMICRMW_SUB Addr, Val, MMO`.
///
@@ -936,8 +1007,8 @@ public:
/// same type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildAtomicRMWSub(unsigned OldValRes, unsigned Addr,
- unsigned Val, MachineMemOperand &MMO);
+ MachineInstrBuilder buildAtomicRMWSub(Register OldValRes, Register Addr,
+ Register Val, MachineMemOperand &MMO);
/// Build and insert `OldValRes<def> = G_ATOMICRMW_AND Addr, Val, MMO`.
///
@@ -951,8 +1022,8 @@ public:
/// same type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildAtomicRMWAnd(unsigned OldValRes, unsigned Addr,
- unsigned Val, MachineMemOperand &MMO);
+ MachineInstrBuilder buildAtomicRMWAnd(Register OldValRes, Register Addr,
+ Register Val, MachineMemOperand &MMO);
/// Build and insert `OldValRes<def> = G_ATOMICRMW_NAND Addr, Val, MMO`.
///
@@ -967,8 +1038,8 @@ public:
/// same type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildAtomicRMWNand(unsigned OldValRes, unsigned Addr,
- unsigned Val, MachineMemOperand &MMO);
+ MachineInstrBuilder buildAtomicRMWNand(Register OldValRes, Register Addr,
+ Register Val, MachineMemOperand &MMO);
/// Build and insert `OldValRes<def> = G_ATOMICRMW_OR Addr, Val, MMO`.
///
@@ -982,8 +1053,8 @@ public:
/// same type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildAtomicRMWOr(unsigned OldValRes, unsigned Addr,
- unsigned Val, MachineMemOperand &MMO);
+ MachineInstrBuilder buildAtomicRMWOr(Register OldValRes, Register Addr,
+ Register Val, MachineMemOperand &MMO);
/// Build and insert `OldValRes<def> = G_ATOMICRMW_XOR Addr, Val, MMO`.
///
@@ -997,8 +1068,8 @@ public:
/// same type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildAtomicRMWXor(unsigned OldValRes, unsigned Addr,
- unsigned Val, MachineMemOperand &MMO);
+ MachineInstrBuilder buildAtomicRMWXor(Register OldValRes, Register Addr,
+ Register Val, MachineMemOperand &MMO);
/// Build and insert `OldValRes<def> = G_ATOMICRMW_MAX Addr, Val, MMO`.
///
@@ -1013,8 +1084,8 @@ public:
/// same type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildAtomicRMWMax(unsigned OldValRes, unsigned Addr,
- unsigned Val, MachineMemOperand &MMO);
+ MachineInstrBuilder buildAtomicRMWMax(Register OldValRes, Register Addr,
+ Register Val, MachineMemOperand &MMO);
/// Build and insert `OldValRes<def> = G_ATOMICRMW_MIN Addr, Val, MMO`.
///
@@ -1029,8 +1100,8 @@ public:
/// same type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildAtomicRMWMin(unsigned OldValRes, unsigned Addr,
- unsigned Val, MachineMemOperand &MMO);
+ MachineInstrBuilder buildAtomicRMWMin(Register OldValRes, Register Addr,
+ Register Val, MachineMemOperand &MMO);
/// Build and insert `OldValRes<def> = G_ATOMICRMW_UMAX Addr, Val, MMO`.
///
@@ -1045,8 +1116,8 @@ public:
/// same type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildAtomicRMWUmax(unsigned OldValRes, unsigned Addr,
- unsigned Val, MachineMemOperand &MMO);
+ MachineInstrBuilder buildAtomicRMWUmax(Register OldValRes, Register Addr,
+ Register Val, MachineMemOperand &MMO);
/// Build and insert `OldValRes<def> = G_ATOMICRMW_UMIN Addr, Val, MMO`.
///
@@ -1061,8 +1132,11 @@ public:
/// same type.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildAtomicRMWUmin(unsigned OldValRes, unsigned Addr,
- unsigned Val, MachineMemOperand &MMO);
+ MachineInstrBuilder buildAtomicRMWUmin(Register OldValRes, Register Addr,
+ Register Val, MachineMemOperand &MMO);
+
+ /// Build and insert `G_FENCE Ordering, Scope`.
+ MachineInstrBuilder buildFence(unsigned Ordering, unsigned Scope);
/// Build and insert \p Res = G_BLOCK_ADDR \p BA
///
@@ -1072,7 +1146,7 @@ public:
/// \pre \p Res must be a generic virtual register of a pointer type.
///
/// \return The newly created instruction.
- MachineInstrBuilder buildBlockAddress(unsigned Res, const BlockAddress *BA);
+ MachineInstrBuilder buildBlockAddress(Register Res, const BlockAddress *BA);
/// Build and insert \p Res = G_ADD \p Op0, \p Op1
///
@@ -1124,6 +1198,36 @@ public:
return buildInstr(TargetOpcode::G_MUL, {Dst}, {Src0, Src1}, Flags);
}
+ MachineInstrBuilder buildUMulH(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_UMULH, {Dst}, {Src0, Src1}, Flags);
+ }
+
+ MachineInstrBuilder buildSMulH(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_SMULH, {Dst}, {Src0, Src1}, Flags);
+ }
+
+ MachineInstrBuilder buildShl(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_SHL, {Dst}, {Src0, Src1}, Flags);
+ }
+
+ MachineInstrBuilder buildLShr(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_LSHR, {Dst}, {Src0, Src1}, Flags);
+ }
+
+ MachineInstrBuilder buildAShr(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_ASHR, {Dst}, {Src0, Src1}, Flags);
+ }
+
/// Build and insert \p Res = G_AND \p Op0, \p Op1
///
/// G_AND sets \p Res to the bitwise and of integer parameters \p Op0 and \p
@@ -1155,6 +1259,137 @@ public:
return buildInstr(TargetOpcode::G_OR, {Dst}, {Src0, Src1});
}
+ /// Build and insert \p Res = G_XOR \p Op0, \p Op1
+ MachineInstrBuilder buildXor(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1) {
+ return buildInstr(TargetOpcode::G_XOR, {Dst}, {Src0, Src1});
+ }
+
+ /// Build and insert a bitwise not,
+ /// \p NegOne = G_CONSTANT -1
+ /// \p Res = G_OR \p Op0, NegOne
+ MachineInstrBuilder buildNot(const DstOp &Dst, const SrcOp &Src0) {
+ auto NegOne = buildConstant(Dst.getLLTTy(*getMRI()), -1);
+ return buildInstr(TargetOpcode::G_XOR, {Dst}, {Src0, NegOne});
+ }
+
+ /// Build and insert \p Res = G_CTPOP \p Op0, \p Src0
+ MachineInstrBuilder buildCTPOP(const DstOp &Dst, const SrcOp &Src0) {
+ return buildInstr(TargetOpcode::G_CTPOP, {Dst}, {Src0});
+ }
+
+ /// Build and insert \p Res = G_CTLZ \p Op0, \p Src0
+ MachineInstrBuilder buildCTLZ(const DstOp &Dst, const SrcOp &Src0) {
+ return buildInstr(TargetOpcode::G_CTLZ, {Dst}, {Src0});
+ }
+
+ /// Build and insert \p Res = G_CTLZ_ZERO_UNDEF \p Op0, \p Src0
+ MachineInstrBuilder buildCTLZ_ZERO_UNDEF(const DstOp &Dst, const SrcOp &Src0) {
+ return buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {Dst}, {Src0});
+ }
+
+ /// Build and insert \p Res = G_CTTZ \p Op0, \p Src0
+ MachineInstrBuilder buildCTTZ(const DstOp &Dst, const SrcOp &Src0) {
+ return buildInstr(TargetOpcode::G_CTTZ, {Dst}, {Src0});
+ }
+
+ /// Build and insert \p Res = G_CTTZ_ZERO_UNDEF \p Op0, \p Src0
+ MachineInstrBuilder buildCTTZ_ZERO_UNDEF(const DstOp &Dst, const SrcOp &Src0) {
+ return buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, {Dst}, {Src0});
+ }
+
+ /// Build and insert \p Res = G_FADD \p Op0, \p Op1
+ MachineInstrBuilder buildFAdd(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1) {
+ return buildInstr(TargetOpcode::G_FADD, {Dst}, {Src0, Src1});
+ }
+
+ /// Build and insert \p Res = G_FSUB \p Op0, \p Op1
+ MachineInstrBuilder buildFSub(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1) {
+ return buildInstr(TargetOpcode::G_FSUB, {Dst}, {Src0, Src1});
+ }
+
+ /// Build and insert \p Res = G_FMA \p Op0, \p Op1, \p Op2
+ MachineInstrBuilder buildFMA(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1, const SrcOp &Src2) {
+ return buildInstr(TargetOpcode::G_FMA, {Dst}, {Src0, Src1, Src2});
+ }
+
+ /// Build and insert \p Res = G_FNEG \p Op0
+ MachineInstrBuilder buildFNeg(const DstOp &Dst, const SrcOp &Src0) {
+ return buildInstr(TargetOpcode::G_FNEG, {Dst}, {Src0});
+ }
+
+ /// Build and insert \p Res = G_FABS \p Op0
+ MachineInstrBuilder buildFAbs(const DstOp &Dst, const SrcOp &Src0) {
+ return buildInstr(TargetOpcode::G_FABS, {Dst}, {Src0});
+ }
+
+ /// Build and insert \p Dst = G_FCANONICALIZE \p Src0
+ MachineInstrBuilder buildFCanonicalize(const DstOp &Dst, const SrcOp &Src0,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_FCANONICALIZE, {Dst}, {Src0}, Flags);
+ }
+
+ /// Build and insert \p Res = G_FCOPYSIGN \p Op0, \p Op1
+ MachineInstrBuilder buildFCopysign(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1) {
+ return buildInstr(TargetOpcode::G_FCOPYSIGN, {Dst}, {Src0, Src1});
+ }
+
+ /// Build and insert \p Res = G_UITOFP \p Src0
+ MachineInstrBuilder buildUITOFP(const DstOp &Dst, const SrcOp &Src0) {
+ return buildInstr(TargetOpcode::G_UITOFP, {Dst}, {Src0});
+ }
+
+ /// Build and insert \p Res = G_SITOFP \p Src0
+ MachineInstrBuilder buildSITOFP(const DstOp &Dst, const SrcOp &Src0) {
+ return buildInstr(TargetOpcode::G_SITOFP, {Dst}, {Src0});
+ }
+
+ /// Build and insert \p Res = G_FPTOUI \p Src0
+ MachineInstrBuilder buildFPTOUI(const DstOp &Dst, const SrcOp &Src0) {
+ return buildInstr(TargetOpcode::G_FPTOUI, {Dst}, {Src0});
+ }
+
+ /// Build and insert \p Res = G_FPTOSI \p Src0
+ MachineInstrBuilder buildFPTOSI(const DstOp &Dst, const SrcOp &Src0) {
+ return buildInstr(TargetOpcode::G_FPTOSI, {Dst}, {Src0});
+ }
+
+ /// Build and insert \p Res = G_SMIN \p Op0, \p Op1
+ MachineInstrBuilder buildSMin(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1) {
+ return buildInstr(TargetOpcode::G_SMIN, {Dst}, {Src0, Src1});
+ }
+
+ /// Build and insert \p Res = G_SMAX \p Op0, \p Op1
+ MachineInstrBuilder buildSMax(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1) {
+ return buildInstr(TargetOpcode::G_SMAX, {Dst}, {Src0, Src1});
+ }
+
+ /// Build and insert \p Res = G_UMIN \p Op0, \p Op1
+ MachineInstrBuilder buildUMin(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1) {
+ return buildInstr(TargetOpcode::G_UMIN, {Dst}, {Src0, Src1});
+ }
+
+ /// Build and insert \p Res = G_UMAX \p Op0, \p Op1
+ MachineInstrBuilder buildUMax(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1) {
+ return buildInstr(TargetOpcode::G_UMAX, {Dst}, {Src0, Src1});
+ }
+
+ /// Build and insert \p Res = G_JUMP_TABLE \p JTI
+ ///
+ /// G_JUMP_TABLE sets \p Res to the address of the jump table specified by
+ /// the jump table index \p JTI.
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildJumpTable(const LLT PtrTy, unsigned JTI);
+
virtual MachineInstrBuilder buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
ArrayRef<SrcOp> SrcOps,
Optional<unsigned> Flags = None);
diff --git a/include/llvm/CodeGen/GlobalISel/RegBankSelect.h b/include/llvm/CodeGen/GlobalISel/RegBankSelect.h
index c53ae416e60b..d9d076ba312c 100644
--- a/include/llvm/CodeGen/GlobalISel/RegBankSelect.h
+++ b/include/llvm/CodeGen/GlobalISel/RegBankSelect.h
@@ -1,9 +1,8 @@
//=- llvm/CodeGen/GlobalISel/RegBankSelect.h - Reg Bank Selector --*- C++ -*-=//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -524,7 +523,7 @@ private:
/// \p OnlyAssign == true means that \p Reg just needs to be assigned a
/// register bank. I.e., no repairing is necessary to have the
/// assignment match.
- bool assignmentMatch(unsigned Reg,
+ bool assignmentMatch(Register Reg,
const RegisterBankInfo::ValueMapping &ValMapping,
bool &OnlyAssign) const;
@@ -563,7 +562,7 @@ private:
bool repairReg(MachineOperand &MO,
const RegisterBankInfo::ValueMapping &ValMapping,
RegBankSelect::RepairingPlacement &RepairPt,
- const iterator_range<SmallVectorImpl<unsigned>::const_iterator>
+ const iterator_range<SmallVectorImpl<Register>::const_iterator>
&NewVRegs);
/// Return the cost of the instruction needed to map \p MO to \p ValMapping.
@@ -634,6 +633,11 @@ public:
MachineFunctionProperties::Property::RegBankSelected);
}
+ MachineFunctionProperties getClearedProperties() const override {
+ return MachineFunctionProperties()
+ .set(MachineFunctionProperties::Property::NoPHIs);
+ }
+
/// Walk through \p MF and assign a register bank to every virtual register
/// that are still mapped to nothing.
/// The target needs to provide a RegisterBankInfo and in particular
diff --git a/include/llvm/CodeGen/GlobalISel/RegisterBank.h b/include/llvm/CodeGen/GlobalISel/RegisterBank.h
index d5612e17393c..f528d1a46012 100644
--- a/include/llvm/CodeGen/GlobalISel/RegisterBank.h
+++ b/include/llvm/CodeGen/GlobalISel/RegisterBank.h
@@ -1,9 +1,8 @@
//==-- llvm/CodeGen/GlobalISel/RegisterBank.h - Register Bank ----*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h b/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
index c33b32b2db40..e84b1c3ea8b1 100644
--- a/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
+++ b/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/GlobalISel/RegisterBankInfo.h ---------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -19,6 +18,7 @@
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
+#include "llvm/CodeGen/Register.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <initializer_list>
@@ -161,6 +161,10 @@ public:
const PartialMapping *begin() const { return BreakDown; }
const PartialMapping *end() const { return BreakDown + NumBreakDowns; }
+ /// \return true if all partial mappings are the same size and register
+ /// bank.
+ bool partsAllUniform() const;
+
/// Check if this ValueMapping is valid.
bool isValid() const { return BreakDown && NumBreakDowns; }
@@ -190,7 +194,7 @@ public:
unsigned Cost = 0;
/// Mapping of all the operands.
- const ValueMapping *OperandsMapping;
+ const ValueMapping *OperandsMapping = nullptr;
/// Number of operands.
unsigned NumOperands = 0;
@@ -207,15 +211,11 @@ public:
/// The rationale is that it is more efficient for the optimizers
/// to be able to assume that the mapping of the ith operand is
/// at the index i.
- ///
- /// \pre ID != InvalidMappingID
InstructionMapping(unsigned ID, unsigned Cost,
const ValueMapping *OperandsMapping,
unsigned NumOperands)
: ID(ID), Cost(Cost), OperandsMapping(OperandsMapping),
NumOperands(NumOperands) {
- assert(getID() != InvalidMappingID &&
- "Use the default constructor for invalid mapping");
}
/// Default constructor.
@@ -282,7 +282,7 @@ public:
SmallVector<int, 8> OpToNewVRegIdx;
/// Hold the registers that will be used to map MI with InstrMapping.
- SmallVector<unsigned, 8> NewVRegs;
+ SmallVector<Register, 8> NewVRegs;
/// Current MachineRegisterInfo, used to create new virtual registers.
MachineRegisterInfo &MRI;
@@ -303,15 +303,15 @@ public:
/// \return The iterator range for the space created.
//
/// \pre getMI().getOperand(OpIdx).isReg()
- iterator_range<SmallVectorImpl<unsigned>::iterator>
+ iterator_range<SmallVectorImpl<Register>::iterator>
getVRegsMem(unsigned OpIdx);
/// Get the end iterator for a range starting at \p StartIdx and
/// spannig \p NumVal in NewVRegs.
/// \pre StartIdx + NumVal <= NewVRegs.size()
- SmallVectorImpl<unsigned>::const_iterator
+ SmallVectorImpl<Register>::const_iterator
getNewVRegsEnd(unsigned StartIdx, unsigned NumVal) const;
- SmallVectorImpl<unsigned>::iterator getNewVRegsEnd(unsigned StartIdx,
+ SmallVectorImpl<Register>::iterator getNewVRegsEnd(unsigned StartIdx,
unsigned NumVal);
public:
@@ -357,7 +357,7 @@ public:
///
/// \post the \p PartialMapIdx-th register of the value mapping of the \p
/// OpIdx-th operand has been set.
- void setVRegs(unsigned OpIdx, unsigned PartialMapIdx, unsigned NewVReg);
+ void setVRegs(unsigned OpIdx, unsigned PartialMapIdx, Register NewVReg);
/// Get all the virtual registers required to map the \p OpIdx-th operand of
/// the instruction.
@@ -371,7 +371,7 @@ public:
///
/// \pre getMI().getOperand(OpIdx).isReg()
/// \pre ForDebug || All partial mappings have been set a register
- iterator_range<SmallVectorImpl<unsigned>::const_iterator>
+ iterator_range<SmallVectorImpl<Register>::const_iterator>
getVRegs(unsigned OpIdx, bool ForDebug = false) const;
/// Print this operands mapper on dbgs() stream.
@@ -435,7 +435,7 @@ protected:
/// Get the MinimalPhysRegClass for Reg.
/// \pre Reg is a physical register.
const TargetRegisterClass &
- getMinimalPhysRegClass(unsigned Reg, const TargetRegisterInfo &TRI) const;
+ getMinimalPhysRegClass(Register Reg, const TargetRegisterInfo &TRI) const;
/// Try to get the mapping of \p MI.
/// See getInstrMapping for more details on what a mapping represents.
@@ -580,7 +580,7 @@ public:
/// or a register bank, then this returns nullptr.
///
/// \pre Reg != 0 (NoRegister)
- const RegisterBank *getRegBank(unsigned Reg, const MachineRegisterInfo &MRI,
+ const RegisterBank *getRegBank(Register Reg, const MachineRegisterInfo &MRI,
const TargetRegisterInfo &TRI) const;
/// Get the total number of register banks.
@@ -618,6 +618,21 @@ public:
return &A != &B;
}
+ /// \returns true if emitting a copy from \p Src to \p Dst is impossible.
+ bool cannotCopy(const RegisterBank &Dst, const RegisterBank &Src,
+ unsigned Size) const {
+ return copyCost(Dst, Src, Size) == std::numeric_limits<unsigned>::max();
+ }
+
+ /// Get the cost of using \p ValMapping to decompose a register. This is
+ /// similar to ::copyCost, except for cases where multiple copy-like
+ /// operations need to be inserted. If the register is used as a source
+ /// operand and already has a bank assigned, \p CurBank is non-null.
+ virtual unsigned getBreakDownCost(const ValueMapping &ValMapping,
+ const RegisterBank *CurBank = nullptr) const {
+ return std::numeric_limits<unsigned>::max();
+ }
+
/// Constrain the (possibly generic) virtual register \p Reg to \p RC.
///
/// \pre \p Reg is a virtual register that either has a bank or a class.
@@ -626,7 +641,7 @@ public:
/// \note Use MachineRegisterInfo::constrainRegAttrs instead for any non-isel
/// purpose, including non-select passes of GlobalISel
static const TargetRegisterClass *
- constrainGenericRegister(unsigned Reg, const TargetRegisterClass &RC,
+ constrainGenericRegister(Register Reg, const TargetRegisterClass &RC,
MachineRegisterInfo &MRI);
/// Identifier used when the related instruction mapping instance
@@ -711,7 +726,7 @@ public:
/// virtual register.
///
/// \pre \p Reg != 0 (NoRegister).
- unsigned getSizeInBits(unsigned Reg, const MachineRegisterInfo &MRI,
+ unsigned getSizeInBits(Register Reg, const MachineRegisterInfo &MRI,
const TargetRegisterInfo &TRI) const;
/// Check that information hold by this instance make sense for the
diff --git a/include/llvm/CodeGen/GlobalISel/Types.h b/include/llvm/CodeGen/GlobalISel/Types.h
index 7b22e343a7f8..4fd7043ba02d 100644
--- a/include/llvm/CodeGen/GlobalISel/Types.h
+++ b/include/llvm/CodeGen/GlobalISel/Types.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/GlobalISel/Types.h - Types used by GISel ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/llvm/CodeGen/GlobalISel/Utils.h b/include/llvm/CodeGen/GlobalISel/Utils.h
index 82b791d35b2b..4cdaa48fb689 100644
--- a/include/llvm/CodeGen/GlobalISel/Utils.h
+++ b/include/llvm/CodeGen/GlobalISel/Utils.h
@@ -1,9 +1,8 @@
//==-- llvm/CodeGen/GlobalISel/Utils.h ---------------------------*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -16,6 +15,7 @@
#define LLVM_CODEGEN_GLOBALISEL_UTILS_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/CodeGen/Register.h"
namespace llvm {
@@ -37,21 +37,37 @@ class ConstantFP;
class APFloat;
/// Try to constrain Reg to the specified register class. If this fails,
-/// create a new virtual register in the correct class and insert a COPY before
-/// \p InsertPt. The debug location of \p InsertPt is used for the new copy.
+/// create a new virtual register in the correct class.
///
/// \return The virtual register constrained to the right register class.
unsigned constrainRegToClass(MachineRegisterInfo &MRI,
const TargetInstrInfo &TII,
- const RegisterBankInfo &RBI,
- MachineInstr &InsertPt, unsigned Reg,
+ const RegisterBankInfo &RBI, unsigned Reg,
const TargetRegisterClass &RegClass);
+/// Constrain the Register operand OpIdx, so that it is now constrained to the
+/// TargetRegisterClass passed as an argument (RegClass).
+/// If this fails, create a new virtual register in the correct class and
+/// insert a COPY before \p InsertPt if it is a use or after if it is a
+/// definition. The debug location of \p InsertPt is used for the new copy.
+///
+/// \return The virtual register constrained to the right register class.
+unsigned constrainOperandRegClass(const MachineFunction &MF,
+ const TargetRegisterInfo &TRI,
+ MachineRegisterInfo &MRI,
+ const TargetInstrInfo &TII,
+ const RegisterBankInfo &RBI,
+ MachineInstr &InsertPt,
+ const TargetRegisterClass &RegClass,
+ const MachineOperand &RegMO, unsigned OpIdx);
+
/// Try to constrain Reg so that it is usable by argument OpIdx of the
/// provided MCInstrDesc \p II. If this fails, create a new virtual
-/// register in the correct class and insert a COPY before \p InsertPt.
-/// This is equivalent to constrainRegToClass() with RegClass obtained from the
-/// MCInstrDesc. The debug location of \p InsertPt is used for the new copy.
+/// register in the correct class and insert a COPY before \p InsertPt
+/// if it is a use or after if it is a definition.
+/// This is equivalent to constrainOperandRegClass(..., RegClass, ...)
+/// with RegClass obtained from the MCInstrDesc. The debug location of \p
+/// InsertPt is used for the new copy.
///
/// \return The virtual register constrained to the right register class.
unsigned constrainOperandRegClass(const MachineFunction &MF,
@@ -90,17 +106,40 @@ void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
const char *PassName, StringRef Msg,
const MachineInstr &MI);
+/// If \p VReg is defined by a G_CONSTANT fits in int64_t
+/// returns it.
Optional<int64_t> getConstantVRegVal(unsigned VReg,
const MachineRegisterInfo &MRI);
+/// Simple struct used to hold a constant integer value and a virtual
+/// register.
+struct ValueAndVReg {
+ int64_t Value;
+ unsigned VReg;
+};
+/// If \p VReg is defined by a statically evaluable chain of
+/// instructions rooted on a G_CONSTANT (\p LookThroughInstrs == true)
+/// and that constant fits in int64_t, returns its value as well as
+/// the virtual register defined by this G_CONSTANT.
+/// When \p LookThroughInstrs == false, this function behaves like
+/// getConstantVRegVal.
+Optional<ValueAndVReg>
+getConstantVRegValWithLookThrough(unsigned VReg, const MachineRegisterInfo &MRI,
+ bool LookThroughInstrs = true);
const ConstantFP* getConstantFPVRegVal(unsigned VReg,
const MachineRegisterInfo &MRI);
/// See if Reg is defined by an single def instruction that is
/// Opcode. Also try to do trivial folding if it's a COPY with
/// same types. Returns null otherwise.
-MachineInstr *getOpcodeDef(unsigned Opcode, unsigned Reg,
+MachineInstr *getOpcodeDef(unsigned Opcode, Register Reg,
const MachineRegisterInfo &MRI);
+/// Find the def instruction for \p Reg, folding away any trivial copies. Note
+/// it may still return a COPY, if it changes the type. May return nullptr if \p
+/// Reg is not a generic virtual register.
+MachineInstr *getDefIgnoringCopies(Register Reg,
+ const MachineRegisterInfo &MRI);
+
/// Returns an APFloat from Val converted to the appropriate size.
APFloat getAPFloatFromSize(double Val, unsigned Size);
@@ -111,5 +150,16 @@ void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU);
Optional<APInt> ConstantFoldBinOp(unsigned Opcode, const unsigned Op1,
const unsigned Op2,
const MachineRegisterInfo &MRI);
+
+/// Returns true if \p Val can be assumed to never be a NaN. If \p SNaN is true,
+/// this returns if \p Val can be assumed to never be a signaling NaN.
+bool isKnownNeverNaN(Register Val, const MachineRegisterInfo &MRI,
+ bool SNaN = false);
+
+/// Returns true if \p Val can be assumed to never be a signaling NaN.
+inline bool isKnownNeverSNaN(Register Val, const MachineRegisterInfo &MRI) {
+ return isKnownNeverNaN(Val, MRI, true);
+}
+
} // End namespace llvm.
#endif
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h
index 9c918ae1104f..acf27dcc5fab 100644
--- a/include/llvm/CodeGen/ISDOpcodes.h
+++ b/include/llvm/CodeGen/ISDOpcodes.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/ISDOpcodes.h - CodeGen opcodes -------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -272,12 +271,17 @@ namespace ISD {
/// resulting value is this minimum value.
SSUBSAT, USUBSAT,
- /// RESULT = SMULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on
+ /// RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on
/// 2 integers with the same width and scale. SCALE represents the scale of
/// both operands as fixed point numbers. This SCALE parameter must be a
/// constant integer. A scale of zero is effectively performing
/// multiplication on 2 integers.
- SMULFIX,
+ SMULFIX, UMULFIX,
+
+ /// Same as the corresponding unsaturated fixed point instructions, but the
+ /// result is clamped between the min and max values representable by the
+ /// bits of the first 2 operands.
+ SMULFIXSAT,
/// Simple binary floating point operators.
FADD, FSUB, FMUL, FDIV, FREM,
@@ -298,6 +302,26 @@ namespace ISD {
STRICT_FRINT, STRICT_FNEARBYINT, STRICT_FMAXNUM, STRICT_FMINNUM,
STRICT_FCEIL, STRICT_FFLOOR, STRICT_FROUND, STRICT_FTRUNC,
+ /// X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating
+ /// point type down to the precision of the destination VT. TRUNC is a
+ /// flag, which is always an integer that is zero or one. If TRUNC is 0,
+ /// this is a normal rounding, if it is 1, this FP_ROUND is known to not
+ /// change the value of Y.
+ ///
+ /// The TRUNC = 1 case is used in cases where we know that the value will
+ /// not be modified by the node, because Y is not using any of the extra
+ /// precision of source type. This allows certain transformations like
+ /// STRICT_FP_EXTEND(STRICT_FP_ROUND(X,1)) -> X which are not safe for
+ /// STRICT_FP_EXTEND(STRICT_FP_ROUND(X,0)) because the extra bits aren't
+ /// removed.
+ /// It is used to limit optimizations while the DAG is being optimized.
+ STRICT_FP_ROUND,
+
+ /// X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP
+ /// type.
+ /// It is used to limit optimizations while the DAG is being optimized.
+ STRICT_FP_EXTEND,
+
/// FMA - Perform a * b + c with no intermediate rounding step.
FMA,
@@ -580,10 +604,14 @@ namespace ISD {
/// is often a storage-only type but has native conversions.
FP16_TO_FP, FP_TO_FP16,
- /// Perform various unary floating-point operations inspired by libm.
+ /// Perform various unary floating-point operations inspired by libm. For
+ /// FPOWI, the result is undefined if if the integer operand doesn't fit
+ /// into 32 bits.
FNEG, FABS, FSQRT, FCBRT, FSIN, FCOS, FPOWI, FPOW,
FLOG, FLOG2, FLOG10, FEXP, FEXP2,
FCEIL, FTRUNC, FRINT, FNEARBYINT, FROUND, FFLOOR,
+ LROUND, LLROUND, LRINT, LLRINT,
+
/// FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two
/// values.
//
@@ -666,6 +694,9 @@ namespace ISD {
/// SDOperands.
INLINEASM,
+ /// INLINEASM_BR - Terminator version of inline asm. Used by asm-goto.
+ INLINEASM_BR,
+
/// EH_LABEL - Represents a label in mid basic block used to track
/// locations needed for debug and exception handling tables. These nodes
/// take a chain as input and return a chain.
@@ -819,6 +850,8 @@ namespace ISD {
ATOMIC_LOAD_MAX,
ATOMIC_LOAD_UMIN,
ATOMIC_LOAD_UMAX,
+ ATOMIC_LOAD_FADD,
+ ATOMIC_LOAD_FSUB,
// Masked load and store - consecutive vector load and store operations
// with additional mask operand that prevents memory accesses to the
@@ -866,11 +899,14 @@ namespace ISD {
VECREDUCE_STRICT_FADD, VECREDUCE_STRICT_FMUL,
/// These reductions are non-strict, and have a single vector operand.
VECREDUCE_FADD, VECREDUCE_FMUL,
+ /// FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
+ VECREDUCE_FMAX, VECREDUCE_FMIN,
+ /// Integer reductions may have a result type larger than the vector element
+ /// type. However, the reduction is performed using the vector element type
+ /// and the value in the top bits is unspecified.
VECREDUCE_ADD, VECREDUCE_MUL,
VECREDUCE_AND, VECREDUCE_OR, VECREDUCE_XOR,
VECREDUCE_SMAX, VECREDUCE_SMIN, VECREDUCE_UMAX, VECREDUCE_UMIN,
- /// FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
- VECREDUCE_FMAX, VECREDUCE_FMIN,
/// BUILTIN_OP_END - This must be the last enum value in this list.
/// The target-specific pre-isel opcode values start here.
diff --git a/include/llvm/CodeGen/IntrinsicLowering.h b/include/llvm/CodeGen/IntrinsicLowering.h
index 597d684909c1..daf2d9a47801 100644
--- a/include/llvm/CodeGen/IntrinsicLowering.h
+++ b/include/llvm/CodeGen/IntrinsicLowering.h
@@ -1,9 +1,8 @@
//===-- IntrinsicLowering.h - Intrinsic Function Lowering -------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -31,10 +30,6 @@ class IntrinsicLowering {
public:
explicit IntrinsicLowering(const DataLayout &DL) : DL(DL), Warned(false) {}
- /// Add all of the prototypes that might be needed by an intrinsic lowering
- /// implementation to be inserted into the module specified.
- void AddPrototypes(Module &M);
-
/// Replace a call to the specified intrinsic function.
/// If an intrinsic function must be implemented by the code generator
/// (such as va_start), this function should print a message and abort.
diff --git a/include/llvm/CodeGen/LatencyPriorityQueue.h b/include/llvm/CodeGen/LatencyPriorityQueue.h
index 9b8d83ce77ca..95f4c6473542 100644
--- a/include/llvm/CodeGen/LatencyPriorityQueue.h
+++ b/include/llvm/CodeGen/LatencyPriorityQueue.h
@@ -1,9 +1,8 @@
//===---- LatencyPriorityQueue.h - A latency-oriented priority queue ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h b/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h
index 221f16a03f16..ca99c6c89b19 100644
--- a/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h
+++ b/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h
@@ -1,9 +1,8 @@
///===- LazyMachineBlockFrequencyInfo.h - Lazy Block Frequency -*- C++ -*--===//
///
-/// The LLVM Compiler Infrastructure
-///
-/// This file is distributed under the University of Illinois Open Source
-/// License. See LICENSE.TXT for details.
+/// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+/// See https://llvm.org/LICENSE.txt for license information.
+/// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
///
///===---------------------------------------------------------------------===//
/// \file
diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h
index 3ba503487823..253d4734995b 100644
--- a/include/llvm/CodeGen/LexicalScopes.h
+++ b/include/llvm/CodeGen/LexicalScopes.h
@@ -1,9 +1,8 @@
//===- LexicalScopes.cpp - Collecting lexical scope info --------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/LinkAllAsmWriterComponents.h b/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
index 38fcb37b1e69..75a5c359630e 100644
--- a/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
+++ b/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
@@ -1,9 +1,8 @@
//===- llvm/Codegen/LinkAllAsmWriterComponents.h ----------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h
index 18c13ca8f598..56c93b24147e 100644
--- a/include/llvm/CodeGen/LinkAllCodegenComponents.h
+++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h
@@ -1,9 +1,8 @@
//===- llvm/Codegen/LinkAllCodegenComponents.h ------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index cdf9ad2588cf..8bb88165d3e1 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/LiveInterval.h - Interval representation ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -606,6 +605,44 @@ namespace llvm {
/// activated in the constructor of the live range.
void flushSegmentSet();
+ /// Stores indexes from the input index sequence R at which this LiveRange
+ /// is live to the output O iterator.
+ /// R is a range of _ascending sorted_ _random_ access iterators
+ /// to the input indexes. Indexes stored at O are ascending sorted so it
+ /// can be used directly in the subsequent search (for example for
+ /// subranges). Returns true if found at least one index.
+ template <typename Range, typename OutputIt>
+ bool findIndexesLiveAt(Range &&R, OutputIt O) const {
+ assert(std::is_sorted(R.begin(), R.end()));
+ auto Idx = R.begin(), EndIdx = R.end();
+ auto Seg = segments.begin(), EndSeg = segments.end();
+ bool Found = false;
+ while (Idx != EndIdx && Seg != EndSeg) {
+ // if the Seg is lower find first segment that is above Idx using binary
+ // search
+ if (Seg->end <= *Idx) {
+ Seg = std::upper_bound(++Seg, EndSeg, *Idx,
+ [=](typename std::remove_reference<decltype(*Idx)>::type V,
+ const typename std::remove_reference<decltype(*Seg)>::type &S) {
+ return V < S.end;
+ });
+ if (Seg == EndSeg)
+ break;
+ }
+ auto NotLessStart = std::lower_bound(Idx, EndIdx, Seg->start);
+ if (NotLessStart == EndIdx)
+ break;
+ auto NotLessEnd = std::lower_bound(NotLessStart, EndIdx, Seg->end);
+ if (NotLessEnd != NotLessStart) {
+ Found = true;
+ O = std::copy(NotLessStart, NotLessEnd, O);
+ }
+ Idx = NotLessEnd;
+ ++Seg;
+ }
+ return Found;
+ }
+
void print(raw_ostream &OS) const;
void dump() const;
@@ -790,8 +827,15 @@ namespace llvm {
/// L000F, refining for mask L0018. Will split the L00F0 lane into
/// L00E0 and L0010 and the L000F lane into L0007 and L0008. The Mod
/// function will be applied to the L0010 and L0008 subranges.
+ ///
+ /// \p Indexes and \p TRI are required to clean up the VNIs that
+ /// don't defne the related lane masks after they get shrunk. E.g.,
+ /// when L000F gets split into L0007 and L0008 maybe only a subset
+ /// of the VNIs that defined L000F defines L0007.
void refineSubRanges(BumpPtrAllocator &Allocator, LaneBitmask LaneMask,
- std::function<void(LiveInterval::SubRange&)> Apply);
+ std::function<void(LiveInterval::SubRange &)> Apply,
+ const SlotIndexes &Indexes,
+ const TargetRegisterInfo &TRI);
bool operator<(const LiveInterval& other) const {
const SlotIndex &thisIndex = beginIndex();
diff --git a/include/llvm/CodeGen/LiveIntervalUnion.h b/include/llvm/CodeGen/LiveIntervalUnion.h
index 9e2799bd4414..05506d2c3bc6 100644
--- a/include/llvm/CodeGen/LiveIntervalUnion.h
+++ b/include/llvm/CodeGen/LiveIntervalUnion.h
@@ -1,9 +1,8 @@
//===- LiveIntervalUnion.h - Live interval union data struct ---*- C++ -*--===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/LiveIntervals.h b/include/llvm/CodeGen/LiveIntervals.h
index 16ab1dc475c4..588b0f9cf39c 100644
--- a/include/llvm/CodeGen/LiveIntervals.h
+++ b/include/llvm/CodeGen/LiveIntervals.h
@@ -1,9 +1,8 @@
//===- LiveIntervals.h - Live Interval Analysis -----------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -418,6 +417,15 @@ class VirtRegMap;
RegUnitRanges[Unit] = nullptr;
}
+ /// Remove associated live ranges for the register units associated with \p
+ /// Reg. Subsequent uses should rely on on-demand recomputation. \note This
+ /// method can result in inconsistent liveness tracking if multiple phyical
+ /// registers share a regunit, and should be used cautiously.
+ void removeAllRegUnitsForPhysReg(unsigned Reg) {
+ for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
+ removeRegUnit(*Units);
+ }
+
/// Remove value numbers and related live segments starting at position
/// \p Pos that are part of any liverange of physical register \p Reg or one
/// of its subregisters.
diff --git a/include/llvm/CodeGen/LivePhysRegs.h b/include/llvm/CodeGen/LivePhysRegs.h
index 7312902e21b7..50da0b3d5c48 100644
--- a/include/llvm/CodeGen/LivePhysRegs.h
+++ b/include/llvm/CodeGen/LivePhysRegs.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/LivePhysRegs.h - Live Physical Register Set -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/LiveRangeEdit.h b/include/llvm/CodeGen/LiveRangeEdit.h
index 53830297c525..6519937ec071 100644
--- a/include/llvm/CodeGen/LiveRangeEdit.h
+++ b/include/llvm/CodeGen/LiveRangeEdit.h
@@ -1,9 +1,8 @@
//===- LiveRangeEdit.h - Basic tools for split and spill --------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/LiveRegMatrix.h b/include/llvm/CodeGen/LiveRegMatrix.h
index f62a55c73085..ab4d44f9a611 100644
--- a/include/llvm/CodeGen/LiveRegMatrix.h
+++ b/include/llvm/CodeGen/LiveRegMatrix.h
@@ -1,9 +1,8 @@
//===- LiveRegMatrix.h - Track register interference ----------*- C++ -*---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/LiveRegUnits.h b/include/llvm/CodeGen/LiveRegUnits.h
index 5e9dd8b3cdf6..7dbb2feab8bf 100644
--- a/include/llvm/CodeGen/LiveRegUnits.h
+++ b/include/llvm/CodeGen/LiveRegUnits.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/LiveRegUnits.h - Register Unit Set ----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/LiveStacks.h b/include/llvm/CodeGen/LiveStacks.h
index 44ed785f7b53..7c4c64d515df 100644
--- a/include/llvm/CodeGen/LiveStacks.h
+++ b/include/llvm/CodeGen/LiveStacks.h
@@ -1,9 +1,8 @@
//===- LiveStacks.h - Live Stack Slot Analysis ------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h
index ed8da8662106..71de306e2942 100644
--- a/include/llvm/CodeGen/LiveVariables.h
+++ b/include/llvm/CodeGen/LiveVariables.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/LiveVariables.h - Live Variable Analysis ---*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/LoopTraversal.h b/include/llvm/CodeGen/LoopTraversal.h
index 750da0143c0d..e5810ef1ef26 100644
--- a/include/llvm/CodeGen/LoopTraversal.h
+++ b/include/llvm/CodeGen/LoopTraversal.h
@@ -1,9 +1,8 @@
//==------ llvm/CodeGen/LoopTraversal.h - Loop Traversal -*- C++ -*---------==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/LowLevelType.h b/include/llvm/CodeGen/LowLevelType.h
index a3c5c9329f53..687233e4e168 100644
--- a/include/llvm/CodeGen/LowLevelType.h
+++ b/include/llvm/CodeGen/LowLevelType.h
@@ -1,9 +1,8 @@
//== llvm/CodeGen/LowLevelType.h ------------------------------- -*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MIRParser/MIParser.h b/include/llvm/CodeGen/MIRParser/MIParser.h
new file mode 100644
index 000000000000..4e32a04551c1
--- /dev/null
+++ b/include/llvm/CodeGen/MIRParser/MIParser.h
@@ -0,0 +1,233 @@
+//===- MIParser.h - Machine Instructions Parser -----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the function that parses the machine instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_CODEGEN_MIRPARSER_MIPARSER_H
+#define LLVM_LIB_CODEGEN_MIRPARSER_MIPARSER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/Support/Allocator.h"
+
+namespace llvm {
+
+class MachineBasicBlock;
+class MachineFunction;
+class MDNode;
+class RegisterBank;
+struct SlotMapping;
+class SMDiagnostic;
+class SourceMgr;
+class StringRef;
+class TargetRegisterClass;
+class TargetSubtargetInfo;
+
+struct VRegInfo {
+ enum uint8_t {
+ UNKNOWN, NORMAL, GENERIC, REGBANK
+ } Kind = UNKNOWN;
+ bool Explicit = false; ///< VReg was explicitly specified in the .mir file.
+ union {
+ const TargetRegisterClass *RC;
+ const RegisterBank *RegBank;
+ } D;
+ unsigned VReg;
+ unsigned PreferredReg = 0;
+};
+
+using Name2RegClassMap = StringMap<const TargetRegisterClass *>;
+using Name2RegBankMap = StringMap<const RegisterBank *>;
+
+struct PerTargetMIParsingState {
+private:
+ const TargetSubtargetInfo &Subtarget;
+
+ /// Maps from instruction names to op codes.
+ StringMap<unsigned> Names2InstrOpCodes;
+
+ /// Maps from register names to registers.
+ StringMap<unsigned> Names2Regs;
+
+ /// Maps from register mask names to register masks.
+ StringMap<const uint32_t *> Names2RegMasks;
+
+ /// Maps from subregister names to subregister indices.
+ StringMap<unsigned> Names2SubRegIndices;
+
+ /// Maps from target index names to target indices.
+ StringMap<int> Names2TargetIndices;
+
+ /// Maps from direct target flag names to the direct target flag values.
+ StringMap<unsigned> Names2DirectTargetFlags;
+
+ /// Maps from direct target flag names to the bitmask target flag values.
+ StringMap<unsigned> Names2BitmaskTargetFlags;
+
+ /// Maps from MMO target flag names to MMO target flag values.
+ StringMap<MachineMemOperand::Flags> Names2MMOTargetFlags;
+
+ /// Maps from register class names to register classes.
+ Name2RegClassMap Names2RegClasses;
+
+ /// Maps from register bank names to register banks.
+ Name2RegBankMap Names2RegBanks;
+
+ void initNames2InstrOpCodes();
+ void initNames2Regs();
+ void initNames2RegMasks();
+ void initNames2SubRegIndices();
+ void initNames2TargetIndices();
+ void initNames2DirectTargetFlags();
+ void initNames2BitmaskTargetFlags();
+ void initNames2MMOTargetFlags();
+
+ void initNames2RegClasses();
+ void initNames2RegBanks();
+
+public:
+ /// Try to convert an instruction name to an opcode. Return true if the
+ /// instruction name is invalid.
+ bool parseInstrName(StringRef InstrName, unsigned &OpCode);
+
+ /// Try to convert a register name to a register number. Return true if the
+ /// register name is invalid.
+ bool getRegisterByName(StringRef RegName, unsigned &Reg);
+
+ /// Check if the given identifier is a name of a register mask.
+ ///
+ /// Return null if the identifier isn't a register mask.
+ const uint32_t *getRegMask(StringRef Identifier);
+
+ /// Check if the given identifier is a name of a subregister index.
+ ///
+ /// Return 0 if the name isn't a subregister index class.
+ unsigned getSubRegIndex(StringRef Name);
+
+ /// Try to convert a name of target index to the corresponding target index.
+ ///
+ /// Return true if the name isn't a name of a target index.
+ bool getTargetIndex(StringRef Name, int &Index);
+
+ /// Try to convert a name of a direct target flag to the corresponding
+ /// target flag.
+ ///
+ /// Return true if the name isn't a name of a direct flag.
+ bool getDirectTargetFlag(StringRef Name, unsigned &Flag);
+
+ /// Try to convert a name of a bitmask target flag to the corresponding
+ /// target flag.
+ ///
+ /// Return true if the name isn't a name of a bitmask target flag.
+ bool getBitmaskTargetFlag(StringRef Name, unsigned &Flag);
+
+ /// Try to convert a name of a MachineMemOperand target flag to the
+ /// corresponding target flag.
+ ///
+ /// Return true if the name isn't a name of a target MMO flag.
+ bool getMMOTargetFlag(StringRef Name, MachineMemOperand::Flags &Flag);
+
+ /// Check if the given identifier is a name of a register class.
+ ///
+ /// Return null if the name isn't a register class.
+ const TargetRegisterClass *getRegClass(StringRef Name);
+
+ /// Check if the given identifier is a name of a register bank.
+ ///
+ /// Return null if the name isn't a register bank.
+ const RegisterBank *getRegBank(StringRef Name);
+
+ PerTargetMIParsingState(const TargetSubtargetInfo &STI)
+ : Subtarget(STI) {
+ initNames2RegClasses();
+ initNames2RegBanks();
+ }
+
+ ~PerTargetMIParsingState() = default;
+
+ void setTarget(const TargetSubtargetInfo &NewSubtarget);
+};
+
+struct PerFunctionMIParsingState {
+ BumpPtrAllocator Allocator;
+ MachineFunction &MF;
+ SourceMgr *SM;
+ const SlotMapping &IRSlots;
+ PerTargetMIParsingState &Target;
+
+ DenseMap<unsigned, MachineBasicBlock *> MBBSlots;
+ DenseMap<unsigned, VRegInfo *> VRegInfos;
+ StringMap<VRegInfo *> VRegInfosNamed;
+ DenseMap<unsigned, int> FixedStackObjectSlots;
+ DenseMap<unsigned, int> StackObjectSlots;
+ DenseMap<unsigned, unsigned> ConstantPoolSlots;
+ DenseMap<unsigned, unsigned> JumpTableSlots;
+
+ PerFunctionMIParsingState(MachineFunction &MF, SourceMgr &SM,
+ const SlotMapping &IRSlots,
+ PerTargetMIParsingState &Target);
+
+ VRegInfo &getVRegInfo(unsigned Num);
+ VRegInfo &getVRegInfoNamed(StringRef RegName);
+};
+
+/// Parse the machine basic block definitions, and skip the machine
+/// instructions.
+///
+/// This function runs the first parsing pass on the machine function's body.
+/// It parses only the machine basic block definitions and creates the machine
+/// basic blocks in the given machine function.
+///
+/// The machine instructions aren't parsed during the first pass because all
+/// the machine basic blocks aren't defined yet - this makes it impossible to
+/// resolve the machine basic block references.
+///
+/// Return true if an error occurred.
+bool parseMachineBasicBlockDefinitions(PerFunctionMIParsingState &PFS,
+ StringRef Src, SMDiagnostic &Error);
+
+/// Parse the machine instructions.
+///
+/// This function runs the second parsing pass on the machine function's body.
+/// It skips the machine basic block definitions and parses only the machine
+/// instructions and basic block attributes like liveins and successors.
+///
+/// The second parsing pass assumes that the first parsing pass already ran
+/// on the given source string.
+///
+/// Return true if an error occurred.
+bool parseMachineInstructions(PerFunctionMIParsingState &PFS, StringRef Src,
+ SMDiagnostic &Error);
+
+bool parseMBBReference(PerFunctionMIParsingState &PFS,
+ MachineBasicBlock *&MBB, StringRef Src,
+ SMDiagnostic &Error);
+
+bool parseRegisterReference(PerFunctionMIParsingState &PFS,
+ unsigned &Reg, StringRef Src,
+ SMDiagnostic &Error);
+
+bool parseNamedRegisterReference(PerFunctionMIParsingState &PFS, unsigned &Reg,
+ StringRef Src, SMDiagnostic &Error);
+
+bool parseVirtualRegisterReference(PerFunctionMIParsingState &PFS,
+ VRegInfo *&Info, StringRef Src,
+ SMDiagnostic &Error);
+
+bool parseStackObjectReference(PerFunctionMIParsingState &PFS, int &FI,
+ StringRef Src, SMDiagnostic &Error);
+
+bool parseMDNode(PerFunctionMIParsingState &PFS, MDNode *&Node, StringRef Src,
+ SMDiagnostic &Error);
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_CODEGEN_MIRPARSER_MIPARSER_H
diff --git a/include/llvm/CodeGen/MIRParser/MIRParser.h b/include/llvm/CodeGen/MIRParser/MIRParser.h
index e199a1f69ad7..6a04e48e533c 100644
--- a/include/llvm/CodeGen/MIRParser/MIRParser.h
+++ b/include/llvm/CodeGen/MIRParser/MIRParser.h
@@ -1,9 +1,8 @@
//===- MIRParser.h - MIR serialization format parser ------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MIRPrinter.h b/include/llvm/CodeGen/MIRPrinter.h
index 078c4b2f6072..a4b03a7fb765 100644
--- a/include/llvm/CodeGen/MIRPrinter.h
+++ b/include/llvm/CodeGen/MIRPrinter.h
@@ -1,9 +1,8 @@
-//===- MIRPrinter.h - MIR serialization format printer --------------------===//
+//===- MIRPrinter.h - MIR serialization format printer ----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MIRYamlMapping.h b/include/llvm/CodeGen/MIRYamlMapping.h
index 98ac81915dc0..94e76a75e8da 100644
--- a/include/llvm/CodeGen/MIRYamlMapping.h
+++ b/include/llvm/CodeGen/MIRYamlMapping.h
@@ -1,9 +1,8 @@
-//===- MIRYAMLMapping.h - Describes the mapping between MIR and YAML ------===//
+//===- MIRYamlMapping.h - Describe mapping between MIR and YAML--*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -18,6 +17,7 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
@@ -37,6 +37,7 @@ struct StringValue {
StringValue() = default;
StringValue(std::string Value) : Value(std::move(Value)) {}
+ StringValue(const char Val[]) : Value(Val) {}
bool operator==(const StringValue &Other) const {
return Value == Other.Value;
@@ -212,7 +213,7 @@ struct MachineStackObject {
int64_t Offset = 0;
uint64_t Size = 0;
unsigned Alignment = 0;
- uint8_t StackID = 0;
+ TargetStackID::Value StackID;
StringValue CalleeSavedRegister;
bool CalleeSavedRestored = true;
Optional<int64_t> LocalOffset;
@@ -252,7 +253,7 @@ template <> struct MappingTraits<MachineStackObject> {
if (Object.Type != MachineStackObject::VariableSized)
YamlIO.mapRequired("size", Object.Size);
YamlIO.mapOptional("alignment", Object.Alignment, (unsigned)0);
- YamlIO.mapOptional("stack-id", Object.StackID);
+ YamlIO.mapOptional("stack-id", Object.StackID, TargetStackID::Default);
YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
StringValue()); // Don't print it out when it's empty.
YamlIO.mapOptional("callee-saved-restored", Object.CalleeSavedRestored,
@@ -278,7 +279,7 @@ struct FixedMachineStackObject {
int64_t Offset = 0;
uint64_t Size = 0;
unsigned Alignment = 0;
- uint8_t StackID = 0;
+ TargetStackID::Value StackID;
bool IsImmutable = false;
bool IsAliased = false;
StringValue CalleeSavedRegister;
@@ -308,6 +309,15 @@ struct ScalarEnumerationTraits<FixedMachineStackObject::ObjectType> {
}
};
+template <>
+struct ScalarEnumerationTraits<TargetStackID::Value> {
+ static void enumeration(yaml::IO &IO, TargetStackID::Value &ID) {
+ IO.enumCase(ID, "default", TargetStackID::Default);
+ IO.enumCase(ID, "sgpr-spill", TargetStackID::SGPRSpill);
+ IO.enumCase(ID, "noalloc", TargetStackID::NoAlloc);
+ }
+};
+
template <> struct MappingTraits<FixedMachineStackObject> {
static void mapping(yaml::IO &YamlIO, FixedMachineStackObject &Object) {
YamlIO.mapRequired("id", Object.ID);
@@ -317,7 +327,7 @@ template <> struct MappingTraits<FixedMachineStackObject> {
YamlIO.mapOptional("offset", Object.Offset, (int64_t)0);
YamlIO.mapOptional("size", Object.Size, (uint64_t)0);
YamlIO.mapOptional("alignment", Object.Alignment, (unsigned)0);
- YamlIO.mapOptional("stack-id", Object.StackID);
+ YamlIO.mapOptional("stack-id", Object.StackID, TargetStackID::Default);
if (Object.Type != FixedMachineStackObject::SpillSlot) {
YamlIO.mapOptional("isImmutable", Object.IsImmutable, false);
YamlIO.mapOptional("isAliased", Object.IsAliased, false);
@@ -337,6 +347,66 @@ template <> struct MappingTraits<FixedMachineStackObject> {
static const bool flow = true;
};
+
+/// Serializable representation of CallSiteInfo.
+struct CallSiteInfo {
+ // Representation of call argument and register which is used to
+ // transfer it.
+ struct ArgRegPair {
+ StringValue Reg;
+ uint16_t ArgNo;
+
+ bool operator==(const ArgRegPair &Other) const {
+ return Reg == Other.Reg && ArgNo == Other.ArgNo;
+ }
+ };
+
+ /// Identifies call instruction location in machine function.
+ struct MachineInstrLoc {
+ unsigned BlockNum;
+ unsigned Offset;
+
+ bool operator==(const MachineInstrLoc &Other) const {
+ return BlockNum == Other.BlockNum && Offset == Other.Offset;
+ }
+ };
+
+ MachineInstrLoc CallLocation;
+ std::vector<ArgRegPair> ArgForwardingRegs;
+
+ bool operator==(const CallSiteInfo &Other) const {
+ return CallLocation.BlockNum == Other.CallLocation.BlockNum &&
+ CallLocation.Offset == Other.CallLocation.Offset;
+ }
+};
+
+template <> struct MappingTraits<CallSiteInfo::ArgRegPair> {
+ static void mapping(IO &YamlIO, CallSiteInfo::ArgRegPair &ArgReg) {
+ YamlIO.mapRequired("arg", ArgReg.ArgNo);
+ YamlIO.mapRequired("reg", ArgReg.Reg);
+ }
+
+ static const bool flow = true;
+};
+}
+}
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::CallSiteInfo::ArgRegPair)
+
+namespace llvm {
+namespace yaml {
+
+template <> struct MappingTraits<CallSiteInfo> {
+ static void mapping(IO &YamlIO, CallSiteInfo &CSInfo) {
+ YamlIO.mapRequired("bb", CSInfo.CallLocation.BlockNum);
+ YamlIO.mapRequired("offset", CSInfo.CallLocation.Offset);
+ YamlIO.mapOptional("fwdArgRegs", CSInfo.ArgForwardingRegs,
+ std::vector<CallSiteInfo::ArgRegPair>());
+ }
+
+ static const bool flow = true;
+};
+
struct MachineConstantPoolValue {
UnsignedValue ID;
StringValue Value;
@@ -391,6 +461,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineFunctionLiveIn)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::CallSiteInfo)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineConstantPoolValue)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineJumpTable::Entry)
@@ -483,6 +554,20 @@ template <> struct MappingTraits<MachineFrameInfo> {
}
};
+/// Targets should override this in a way that mirrors the implementation of
+/// llvm::MachineFunctionInfo.
+struct MachineFunctionInfo {
+ virtual ~MachineFunctionInfo() {}
+ virtual void mappingImpl(IO &YamlIO) {}
+};
+
+template <> struct MappingTraits<std::unique_ptr<MachineFunctionInfo>> {
+ static void mapping(IO &YamlIO, std::unique_ptr<MachineFunctionInfo> &MFI) {
+ if (MFI)
+ MFI->mappingImpl(YamlIO);
+ }
+};
+
struct MachineFunction {
StringRef Name;
unsigned Alignment = 0;
@@ -504,6 +589,8 @@ struct MachineFunction {
std::vector<FixedMachineStackObject> FixedStackObjects;
std::vector<MachineStackObject> StackObjects;
std::vector<MachineConstantPoolValue> Constants; /// Constant pool.
+ std::unique_ptr<MachineFunctionInfo> MachineFuncInfo;
+ std::vector<CallSiteInfo> CallSitesInfo;
MachineJumpTable JumpTableInfo;
BlockStringValue Body;
};
@@ -530,8 +617,11 @@ template <> struct MappingTraits<MachineFunction> {
std::vector<FixedMachineStackObject>());
YamlIO.mapOptional("stack", MF.StackObjects,
std::vector<MachineStackObject>());
+ YamlIO.mapOptional("callSites", MF.CallSitesInfo,
+ std::vector<CallSiteInfo>());
YamlIO.mapOptional("constants", MF.Constants,
std::vector<MachineConstantPoolValue>());
+ YamlIO.mapOptional("machineFunctionInfo", MF.MachineFuncInfo);
if (!YamlIO.outputting() || !MF.JumpTableInfo.Entries.empty())
YamlIO.mapOptional("jumpTable", MF.JumpTableInfo, MachineJumpTable());
YamlIO.mapOptional("body", MF.Body, BlockStringValue());
diff --git a/include/llvm/CodeGen/MachORelocation.h b/include/llvm/CodeGen/MachORelocation.h
index cbb49695af75..0185c7cbe018 100644
--- a/include/llvm/CodeGen/MachORelocation.h
+++ b/include/llvm/CodeGen/MachORelocation.h
@@ -1,9 +1,8 @@
//=== MachORelocation.h - Mach-O Relocation Info ----------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
index ec2f270fcb3f..333d0a78618c 100644
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/MachineBasicBlock.h -------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -115,6 +114,10 @@ private:
/// branch.
bool AddressTaken = false;
+ /// Indicate that this basic block needs its symbol be emitted regardless of
+ /// whether the flow just falls-through to it.
+ bool LabelMustBeEmitted = false;
+
/// Indicate that this basic block is the entry block of an EH scope, i.e.,
/// the block that used to have a catchpad or cleanuppad instruction in the
/// LLVM IR.
@@ -159,6 +162,13 @@ public:
/// branch.
void setHasAddressTaken() { AddressTaken = true; }
+ /// Test whether this block must have its label emitted.
+ bool hasLabelMustBeEmitted() const { return LabelMustBeEmitted; }
+
+ /// Set this block to reflect that, regardless how we flow to it, we need
+ /// its label be emitted.
+ void setLabelMustBeEmitted() { LabelMustBeEmitted = true; }
+
/// Return the MachineFunction containing this basic block.
const MachineFunction *getParent() const { return xParent; }
MachineFunction *getParent() { return xParent; }
@@ -900,11 +910,11 @@ class MachineInstrSpan {
MachineBasicBlock::iterator I, B, E;
public:
- MachineInstrSpan(MachineBasicBlock::iterator I)
- : MBB(*I->getParent()),
- I(I),
- B(I == MBB.begin() ? MBB.end() : std::prev(I)),
- E(std::next(I)) {}
+ MachineInstrSpan(MachineBasicBlock::iterator I, MachineBasicBlock *BB)
+ : MBB(*BB), I(I), B(I == MBB.begin() ? MBB.end() : std::prev(I)),
+ E(std::next(I)) {
+ assert(I == BB->end() || I->getParent() == BB);
+ }
MachineBasicBlock::iterator begin() {
return B == MBB.end() ? MBB.begin() : std::next(B);
diff --git a/include/llvm/CodeGen/MachineBlockFrequencyInfo.h b/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
index 5b4b99ca0a5d..a438ecfcc25e 100644
--- a/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
+++ b/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
@@ -1,9 +1,8 @@
//===- MachineBlockFrequencyInfo.h - MBB Frequency Analysis -----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
index 81b0524cf0a4..2b9b2030eb97 100644
--- a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
+++ b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
@@ -1,9 +1,8 @@
//=- MachineBranchProbabilityInfo.h - Branch Probability Analysis -*- C++ -*-=//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MachineCombinerPattern.h b/include/llvm/CodeGen/MachineCombinerPattern.h
index 586535f771c2..4f4034baf801 100644
--- a/include/llvm/CodeGen/MachineCombinerPattern.h
+++ b/include/llvm/CodeGen/MachineCombinerPattern.h
@@ -1,10 +1,9 @@
//===-- llvm/CodeGen/MachineCombinerPattern.h - Instruction pattern supported by
// combiner ------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h
index b0b5420a884b..4d07b620a4b4 100644
--- a/include/llvm/CodeGen/MachineConstantPool.h
+++ b/include/llvm/CodeGen/MachineConstantPool.h
@@ -1,9 +1,8 @@
//===- CodeGen/MachineConstantPool.h - Abstract Constant Pool ---*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MachineDominanceFrontier.h b/include/llvm/CodeGen/MachineDominanceFrontier.h
index 75d75bc3669a..f7bbd07a63ab 100644
--- a/include/llvm/CodeGen/MachineDominanceFrontier.h
+++ b/include/llvm/CodeGen/MachineDominanceFrontier.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/MachineDominanceFrontier.h ------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/MachineDominators.h b/include/llvm/CodeGen/MachineDominators.h
index e3d3d169db97..d2200080b897 100644
--- a/include/llvm/CodeGen/MachineDominators.h
+++ b/include/llvm/CodeGen/MachineDominators.h
@@ -1,9 +1,8 @@
//==- llvm/CodeGen/MachineDominators.h - Machine Dom Calculation -*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index c2706a21a177..761735120a64 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -1,9 +1,8 @@
//===-- CodeGen/MachineFrameInfo.h - Abstract Stack Frame Rep. --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -471,7 +470,10 @@ public:
assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
"Invalid Object Idx!");
Objects[ObjectIdx+NumFixedObjects].Alignment = Align;
- ensureMaxAlignment(Align);
+
+ // Only ensure max alignment for the default stack.
+ if (getStackID(ObjectIdx) == 0)
+ ensureMaxAlignment(Align);
}
/// Return the underlying Alloca of the specified
@@ -698,6 +700,8 @@ public:
assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
"Invalid Object Idx!");
Objects[ObjectIdx+NumFixedObjects].StackID = ID;
+ // If ID > 0, MaxAlignment may now be overly conservative.
+ // If ID == 0, MaxAlignment will need to be updated separately.
}
/// Returns true if the specified index corresponds to a dead object.
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
index 25edf5bcce51..201c126ee52e 100644
--- a/include/llvm/CodeGen/MachineFunction.h
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/MachineFunction.h ---------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -31,11 +30,6 @@
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineMemOperand.h"
-#include "llvm/IR/DebugLoc.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Metadata.h"
-#include "llvm/MC/MCDwarf.h"
-#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ArrayRecycler.h"
#include "llvm/Support/AtomicOrdering.h"
@@ -53,6 +47,7 @@ namespace llvm {
class BasicBlock;
class BlockAddress;
class DataLayout;
+class DebugLoc;
class DIExpression;
class DILocalVariable;
class DILocation;
@@ -67,6 +62,7 @@ class MachineModuleInfo;
class MachineRegisterInfo;
class MCContext;
class MCInstrDesc;
+class MCSymbol;
class Pass;
class PseudoSourceValueManager;
class raw_ostream;
@@ -86,7 +82,7 @@ template <> struct ilist_callback_traits<MachineBasicBlock> {
template <class Iterator>
void transferNodesFromList(ilist_callback_traits &OldList, Iterator, Iterator) {
- llvm_unreachable("Never transfer between lists");
+ assert(this == &OldList && "never transfer MBBs between functions");
}
};
@@ -325,6 +321,10 @@ class MachineFunction {
/// CodeView label annotations.
std::vector<std::pair<MCSymbol *, MDNode *>> CodeViewAnnotations;
+ /// CodeView heapallocsites.
+ std::vector<std::tuple<MCSymbol*, MCSymbol*, DIType*>>
+ CodeViewHeapAllocSites;
+
bool CallsEHReturn = false;
bool CallsUnwindInit = false;
bool HasEHScopes = false;
@@ -378,9 +378,28 @@ public:
virtual void MF_HandleRemoval(MachineInstr &MI) = 0;
};
+ /// Structure used to represent pair of argument number after call lowering
+ /// and register used to transfer that argument.
+ /// For now we support only cases when argument is transferred through one
+ /// register.
+ struct ArgRegPair {
+ unsigned Reg;
+ uint16_t ArgNo;
+ ArgRegPair(unsigned R, unsigned Arg) : Reg(R), ArgNo(Arg) {
+ assert(Arg < (1 << 16) && "Arg out of range");
+ }
+ };
+ /// Vector of call argument and its forwarding register.
+ using CallSiteInfo = SmallVector<ArgRegPair, 1>;
+ using CallSiteInfoImpl = SmallVectorImpl<ArgRegPair>;
+
private:
Delegate *TheDelegate = nullptr;
+ using CallSiteInfoMap = DenseMap<const MachineInstr *, CallSiteInfo>;
+ /// Map a call instruction to call site arguments forwarding info.
+ CallSiteInfoMap CallSitesInfo;
+
// Callbacks for insertion and removal.
void handleInsertion(MachineInstr &MI);
void handleRemoval(MachineInstr &MI);
@@ -443,7 +462,6 @@ public:
/// getSubtarget - Return the subtarget for which this machine code is being
/// compiled.
const TargetSubtargetInfo &getSubtarget() const { return *STI; }
- void setSubtarget(const TargetSubtargetInfo *ST) { STI = ST; }
/// getSubtarget - This method returns a pointer to the specified type of
/// TargetSubtargetInfo. In debug builds, it verifies that the object being
@@ -741,6 +759,12 @@ public:
MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
const AAMDNodes &AAInfo);
+ /// Allocate a new MachineMemOperand by copying an existing one,
+ /// replacing the flags. MachineMemOperands are owned
+ /// by the MachineFunction and need not be explicitly deallocated.
+ MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
+ MachineMemOperand::Flags Flags);
+
using OperandCapacity = ArrayRecycler<MachineOperand>::Capacity;
/// Allocate an array of MachineOperands. This is only intended for use by
@@ -791,10 +815,7 @@ public:
return FrameInstructions;
}
- LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst) {
- FrameInstructions.push_back(Inst);
- return FrameInstructions.size() - 1;
- }
+ LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst);
/// \name Exception Handling
/// \{
@@ -913,6 +934,14 @@ public:
return CodeViewAnnotations;
}
+ /// Record heapallocsites
+ void addCodeViewHeapAllocSite(MachineInstr *I, MDNode *MD);
+
+ ArrayRef<std::tuple<MCSymbol*, MCSymbol*, DIType*>>
+ getCodeViewHeapAllocSites() const {
+ return CodeViewHeapAllocSites;
+ }
+
/// Return a reference to the C++ typeinfo for the current function.
const std::vector<const GlobalValue *> &getTypeInfos() const {
return TypeInfos;
@@ -936,6 +965,23 @@ public:
const VariableDbgInfoMapTy &getVariableDbgInfo() const {
return VariableDbgInfos;
}
+
+ void addCallArgsForwardingRegs(const MachineInstr *CallI,
+ CallSiteInfoImpl &&CallInfo) {
+ assert(CallI->isCall());
+ CallSitesInfo[CallI] = std::move(CallInfo);
+ }
+
+ const CallSiteInfoMap &getCallSitesInfo() const {
+ return CallSitesInfo;
+ }
+
+ /// Update call sites info by deleting entry for \p Old call instruction.
+ /// If \p New is present then transfer \p Old call info to it. This function
+ /// should be called before removing call instruction or before replacing
+ /// call instruction with new one.
+ void updateCallSiteInfo(const MachineInstr *Old,
+ const MachineInstr *New = nullptr);
};
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/MachineFunctionPass.h b/include/llvm/CodeGen/MachineFunctionPass.h
index 6d978daa2018..caaf22c2139e 100644
--- a/include/llvm/CodeGen/MachineFunctionPass.h
+++ b/include/llvm/CodeGen/MachineFunctionPass.h
@@ -1,9 +1,8 @@
//===-- MachineFunctionPass.h - Pass for MachineFunctions --------*-C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index ea1a2a536fc7..c82c5b137507 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/MachineInstr.h - MachineInstr class ---------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -25,6 +24,7 @@
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/TargetOpcodes.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/MC/MCInstrDesc.h"
@@ -103,8 +103,10 @@ public:
// no unsigned wrap.
NoSWrap = 1 << 12, // Instruction supports binary operator
// no signed wrap.
- IsExact = 1 << 13 // Instruction supports division is
+ IsExact = 1 << 13, // Instruction supports division is
// known to be exact.
+ FPExcept = 1 << 14, // Instruction may raise floating-point
+ // exceptions.
};
private:
@@ -831,6 +833,17 @@ public:
return mayLoad(Type) || mayStore(Type);
}
+ /// Return true if this instruction could possibly raise a floating-point
+ /// exception. This is the case if the instruction is a floating-point
+ /// instruction that can in principle raise an exception, as indicated
+ /// by the MCID::MayRaiseFPException property, *and* at the same time,
+ /// the instruction is used in a context where we expect floating-point
+ /// exceptions might be enabled, as indicated by the FPExcept MI flag.
+ bool mayRaiseFPException() const {
+ return hasProperty(MCID::MayRaiseFPException) &&
+ getFlag(MachineInstr::MIFlag::FPExcept);
+ }
+
//===--------------------------------------------------------------------===//
// Flags that indicate whether an instruction can be modified by a method.
//===--------------------------------------------------------------------===//
@@ -1006,16 +1019,33 @@ public:
&& getOperand(1).isImm();
}
+ /// A DBG_VALUE is an entry value iff its debug expression contains the
+ /// DW_OP_entry_value DWARF operation.
+ bool isDebugEntryValue() const {
+ return isDebugValue() && getDebugExpression()->isEntryValue();
+ }
+
+ /// Return true if the instruction is a debug value which describes a part of
+ /// a variable as unavailable.
+ bool isUndefDebugValue() const {
+ return isDebugValue() && getOperand(0).isReg() && !getOperand(0).getReg();
+ }
+
bool isPHI() const {
return getOpcode() == TargetOpcode::PHI ||
getOpcode() == TargetOpcode::G_PHI;
}
bool isKill() const { return getOpcode() == TargetOpcode::KILL; }
bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; }
- bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; }
+ bool isInlineAsm() const {
+ return getOpcode() == TargetOpcode::INLINEASM ||
+ getOpcode() == TargetOpcode::INLINEASM_BR;
+ }
+ /// FIXME: Seems like a layering violation that the AsmDialect, which is X86
+ /// specific, be attached to a generic MachineInstr.
bool isMSInlineAsm() const {
- return getOpcode() == TargetOpcode::INLINEASM && getInlineAsmDialect();
+ return isInlineAsm() && getInlineAsmDialect() == InlineAsm::AD_Intel;
}
bool isStackAligningInlineAsm() const;
@@ -1197,12 +1227,22 @@ public:
/// Wrapper for findRegisterDefOperandIdx, it returns
/// a pointer to the MachineOperand rather than an index.
- MachineOperand *findRegisterDefOperand(unsigned Reg, bool isDead = false,
- const TargetRegisterInfo *TRI = nullptr) {
- int Idx = findRegisterDefOperandIdx(Reg, isDead, false, TRI);
+ MachineOperand *
+ findRegisterDefOperand(unsigned Reg, bool isDead = false,
+ bool Overlap = false,
+ const TargetRegisterInfo *TRI = nullptr) {
+ int Idx = findRegisterDefOperandIdx(Reg, isDead, Overlap, TRI);
return (Idx == -1) ? nullptr : &getOperand(Idx);
}
+ const MachineOperand *
+ findRegisterDefOperand(unsigned Reg, bool isDead = false,
+ bool Overlap = false,
+ const TargetRegisterInfo *TRI = nullptr) const {
+ return const_cast<MachineInstr *>(this)->findRegisterDefOperand(
+ Reg, isDead, Overlap, TRI);
+ }
+
/// Find the index of the first operand in the
/// operand list that is used to represent the predicate. It returns -1 if
/// none is found.
@@ -1364,7 +1404,7 @@ public:
/// @param AA Optional alias analysis, used to compare memory operands.
/// @param Other MachineInstr to check aliasing against.
/// @param UseTBAA Whether to pass TBAA information to alias analysis.
- bool mayAlias(AliasAnalysis *AA, MachineInstr &Other, bool UseTBAA);
+ bool mayAlias(AliasAnalysis *AA, const MachineInstr &Other, bool UseTBAA) const;
/// Return true if this instruction may have an ordered
/// or volatile memory reference, or if the information describing the memory
@@ -1400,6 +1440,19 @@ public:
/// Return true if all the defs of this instruction are dead.
bool allDefsAreDead() const;
+ /// Return a valid size if the instruction is a spill instruction.
+ Optional<unsigned> getSpillSize(const TargetInstrInfo *TII) const;
+
+ /// Return a valid size if the instruction is a folded spill instruction.
+ Optional<unsigned> getFoldedSpillSize(const TargetInstrInfo *TII) const;
+
+ /// Return a valid size if the instruction is a restore instruction.
+ Optional<unsigned> getRestoreSize(const TargetInstrInfo *TII) const;
+
+ /// Return a valid size if the instruction is a folded restore instruction.
+ Optional<unsigned>
+ getFoldedRestoreSize(const TargetInstrInfo *TII) const;
+
/// Copy implicit register operands from specified
/// instruction to this instruction.
void copyImplicitOps(MachineFunction &MF, const MachineInstr &MI);
@@ -1521,11 +1574,17 @@ public:
/// FIXME: This is not fully implemented yet.
void setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol);
+ /// Clone another MachineInstr's pre- and post- instruction symbols and
+ /// replace ours with it.
+ void cloneInstrSymbols(MachineFunction &MF, const MachineInstr &MI);
+
/// Return the MIFlags which represent both MachineInstrs. This
/// should be used when merging two MachineInstrs into one. This routine does
/// not modify the MIFlags of this MachineInstr.
uint16_t mergeFlagsWith(const MachineInstr& Other) const;
+ static uint16_t copyFlagsFromInstruction(const Instruction &I);
+
/// Copy all flags to MachineInst MIFlags
void copyIRFlags(const Instruction &I);
diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h
index b5e523f655e7..6d7fb72b6bd1 100644
--- a/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -1,9 +1,8 @@
//===- CodeGen/MachineInstrBuilder.h - Simplify creation of MIs --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -80,6 +79,11 @@ public:
/// explicitly.
MachineInstr *getInstr() const { return MI; }
+ /// Get the register for the operand index.
+ /// The operand at the index should be a register (asserted by
+ /// MachineOperand).
+ Register getReg(unsigned Idx) const { return MI->getOperand(Idx).getReg(); }
+
/// Add a new virtual register operand.
const MachineInstrBuilder &addReg(unsigned RegNo, unsigned flags = 0,
unsigned SubReg = 0) const {
@@ -283,6 +287,9 @@ public:
case MachineOperand::MO_GlobalAddress:
return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off,
TargetFlags);
+ case MachineOperand::MO_BlockAddress:
+ return addBlockAddress(Disp.getBlockAddress(), Disp.getOffset() + off,
+ TargetFlags);
}
}
diff --git a/include/llvm/CodeGen/MachineInstrBundle.h b/include/llvm/CodeGen/MachineInstrBundle.h
index b5341fd1ae49..1810d23072d0 100644
--- a/include/llvm/CodeGen/MachineInstrBundle.h
+++ b/include/llvm/CodeGen/MachineInstrBundle.h
@@ -1,9 +1,8 @@
-//===-- CodeGen/MachineInstBundle.h - MI bundle utilities -------*- C++ -*-===//
+//===- llvm/CodeGen/MachineInstrBundle.h - MI bundle utilities --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -62,7 +61,8 @@ inline MachineBasicBlock::instr_iterator getBundleEnd(
MachineBasicBlock::instr_iterator I) {
while (I->isBundledWithSucc())
++I;
- return ++I;
+ ++I;
+ return I;
}
/// Returns an iterator pointing beyond the bundle containing \p I.
@@ -70,7 +70,8 @@ inline MachineBasicBlock::const_instr_iterator getBundleEnd(
MachineBasicBlock::const_instr_iterator I) {
while (I->isBundledWithSucc())
++I;
- return ++I;
+ ++I;
+ return I;
}
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/MachineInstrBundleIterator.h b/include/llvm/CodeGen/MachineInstrBundleIterator.h
index 5fe4964ff116..0f59563e7e1b 100644
--- a/include/llvm/CodeGen/MachineInstrBundleIterator.h
+++ b/include/llvm/CodeGen/MachineInstrBundleIterator.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/MachineInstrBundleIterator.h ----------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h
index 25a3e6b556a3..11781145b378 100644
--- a/include/llvm/CodeGen/MachineJumpTableInfo.h
+++ b/include/llvm/CodeGen/MachineJumpTableInfo.h
@@ -1,9 +1,8 @@
//===-- CodeGen/MachineJumpTableInfo.h - Abstract Jump Tables --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h
index 917fb90380f5..da6df59c739c 100644
--- a/include/llvm/CodeGen/MachineLoopInfo.h
+++ b/include/llvm/CodeGen/MachineLoopInfo.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/MachineLoopInfo.h - Natural Loop Calculator -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h
index 078ef7ca510c..65f706302bc2 100644
--- a/include/llvm/CodeGen/MachineMemOperand.h
+++ b/include/llvm/CodeGen/MachineMemOperand.h
@@ -1,9 +1,8 @@
//==- llvm/CodeGen/MachineMemOperand.h - MachineMemOperand class -*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -19,8 +18,6 @@
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Metadata.h"
#include "llvm/IR/Value.h" // PointerLikeTypeTraits<Value*>
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/DataTypes.h"
@@ -223,6 +220,9 @@ public:
/// Return the size in bytes of the memory reference.
uint64_t getSize() const { return Size; }
+ /// Return the size in bits of the memory reference.
+ uint64_t getSizeInBits() const { return Size * 8; }
+
/// Return the minimum known alignment in bytes of the actual memory
/// reference.
uint64_t getAlignment() const;
@@ -267,13 +267,13 @@ public:
bool isAtomic() const { return getOrdering() != AtomicOrdering::NotAtomic; }
/// Returns true if this memory operation doesn't have any ordering
- /// constraints other than normal aliasing. Volatile and atomic memory
- /// operations can't be reordered.
- ///
- /// Currently, we don't model the difference between volatile and atomic
- /// operations. They should retain their ordering relative to all memory
- /// operations.
- bool isUnordered() const { return !isVolatile(); }
+ /// constraints other than normal aliasing. Volatile and (ordered) atomic
+ /// memory operations can't be reordered.
+ bool isUnordered() const {
+ return (getOrdering() == AtomicOrdering::NotAtomic ||
+ getOrdering() == AtomicOrdering::Unordered) &&
+ !isVolatile();
+ }
/// Update this MachineMemOperand to reflect the alignment of MMO, if it has a
/// greater alignment. This must only be used when the new alignment applies
diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h
index 4371420bc7a2..4ff5c7fd013a 100644
--- a/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/include/llvm/CodeGen/MachineModuleInfo.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/MachineModuleInfo.h ------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -114,10 +113,9 @@ class MachineModuleInfo : public ImmutablePass {
/// True if debugging information is available in this module.
bool DbgInfoAvailable;
- /// True if this module calls VarArg function with floating-point arguments.
- /// This is used to emit an undefined reference to _fltused on Windows
- /// targets.
- bool UsesVAFloatArgument;
+ /// True if this module is being built for windows/msvc, and uses floating
+ /// point. This is used to emit an undefined reference to _fltused.
+ bool UsesMSVCFloatingPoint;
/// True if the module calls the __morestack function indirectly, as is
/// required under the large code model on x86. This is used to emit
@@ -152,6 +150,8 @@ public:
bool doInitialization(Module &) override;
bool doFinalization(Module &) override;
+ const LLVMTargetMachine &getTarget() const { return TM; }
+
const MCContext &getContext() const { return Context; }
MCContext &getContext() { return Context; }
@@ -187,13 +187,9 @@ public:
bool hasDebugInfo() const { return DbgInfoAvailable; }
void setDebugInfoAvailability(bool avail) { DbgInfoAvailable = avail; }
- bool usesVAFloatArgument() const {
- return UsesVAFloatArgument;
- }
+ bool usesMSVCFloatingPoint() const { return UsesMSVCFloatingPoint; }
- void setUsesVAFloatArgument(bool b) {
- UsesVAFloatArgument = b;
- }
+ void setUsesMSVCFloatingPoint(bool b) { UsesMSVCFloatingPoint = b; }
bool usesMorestackAddr() const {
return UsesMorestackAddr;
@@ -258,14 +254,6 @@ public:
/// \}
}; // End class MachineModuleInfo
-//===- MMI building helpers -----------------------------------------------===//
-
-/// Determine if any floating-point values are being passed to this variadic
-/// function, and set the MachineModuleInfo's usesVAFloatArgument flag if so.
-/// This flag is used to emit an undefined reference to _fltused on Windows,
-/// which will link in MSVCRT's floating-point support.
-void computeUsesVAFloatArgument(const CallInst &I, MachineModuleInfo &MMI);
-
} // end namespace llvm
#endif // LLVM_CODEGEN_MACHINEMODULEINFO_H
diff --git a/include/llvm/CodeGen/MachineModuleInfoImpls.h b/include/llvm/CodeGen/MachineModuleInfoImpls.h
index 17df1fa792b7..746e92239613 100644
--- a/include/llvm/CodeGen/MachineModuleInfoImpls.h
+++ b/include/llvm/CodeGen/MachineModuleInfoImpls.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/MachineModuleInfoImpls.h --------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
index 53e8889d118a..2152c7582e5a 100644
--- a/include/llvm/CodeGen/MachineOperand.h
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/MachineOperand.h - MachineOperand class ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -15,6 +14,7 @@
#define LLVM_CODEGEN_MACHINEOPERAND_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/Register.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/LowLevelTypeImpl.h"
@@ -346,9 +346,9 @@ public:
//===--------------------------------------------------------------------===//
/// getReg - Returns the register number.
- unsigned getReg() const {
+ Register getReg() const {
assert(isReg() && "This is not a register operand!");
- return SmallContents.RegNo;
+ return Register(SmallContents.RegNo);
}
unsigned getSubReg() const {
@@ -684,6 +684,11 @@ public:
Contents.RegMask = RegMaskPtr;
}
+ void setPredicate(unsigned Predicate) {
+ assert(isPredicate() && "Wrong MachineOperand mutator");
+ Contents.Pred = Predicate;
+ }
+
//===--------------------------------------------------------------------===//
// Other methods.
//===--------------------------------------------------------------------===//
@@ -714,6 +719,10 @@ public:
/// ChangeToES - Replace this operand with a new external symbol operand.
void ChangeToES(const char *SymName, unsigned char TargetFlags = 0);
+ /// ChangeToGA - Replace this operand with a new global address operand.
+ void ChangeToGA(const GlobalValue *GV, int64_t Offset,
+ unsigned char TargetFlags = 0);
+
/// ChangeToMCSymbol - Replace this operand with a new MC symbol operand.
void ChangeToMCSymbol(MCSymbol *Sym);
diff --git a/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h b/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
index a7ce870400c2..a461a299917c 100644
--- a/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
+++ b/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
@@ -1,9 +1,8 @@
///===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*----===//
///
-/// The LLVM Compiler Infrastructure
-///
-/// This file is distributed under the University of Illinois Open Source
-/// License. See LICENSE.TXT for details.
+/// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+/// See https://llvm.org/LICENSE.txt for license information.
+/// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
///
///===---------------------------------------------------------------------===//
/// \file
@@ -159,9 +158,10 @@ public:
/// (1) to filter trivial false positives or (2) to provide more context so
/// that non-trivial false positives can be quickly detected by the user.
bool allowExtraAnalysis(StringRef PassName) const {
- return (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
- MF.getFunction().getContext()
- .getDiagHandlerPtr()->isAnyRemarkEnabled(PassName));
+ return (
+ MF.getFunction().getContext().getRemarkStreamer() ||
+ MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(
+ PassName));
}
/// Take a lambda that returns a remark which will be emitted. Second
@@ -172,8 +172,11 @@ public:
// remarks enabled. We can't currently check whether remarks are requested
// for the calling pass since that requires actually building the remark.
- if (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
- MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()) {
+ if (MF.getFunction().getContext().getRemarkStreamer() ||
+ MF.getFunction()
+ .getContext()
+ .getDiagHandlerPtr()
+ ->isAnyRemarkEnabled()) {
auto R = RemarkBuilder();
emit((DiagnosticInfoOptimizationBase &)R);
}
diff --git a/include/llvm/CodeGen/MachineOutliner.h b/include/llvm/CodeGen/MachineOutliner.h
index bfd1e994053a..3868fa415579 100644
--- a/include/llvm/CodeGen/MachineOutliner.h
+++ b/include/llvm/CodeGen/MachineOutliner.h
@@ -1,9 +1,8 @@
//===---- MachineOutliner.h - Outliner data structures ------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
@@ -172,13 +171,13 @@ public:
/// Represents the size of a sequence in bytes. (Some instructions vary
/// widely in size, so just counting the instructions isn't very useful.)
- unsigned SequenceSize;
+ unsigned SequenceSize = 0;
/// Target-defined overhead of constructing a frame for this function.
- unsigned FrameOverhead;
+ unsigned FrameOverhead = 0;
/// Target-defined identifier for constructing a frame for this function.
- unsigned FrameConstructionID;
+ unsigned FrameConstructionID = 0;
/// Return the number of candidates for this \p OutlinedFunction.
unsigned getOccurrenceCount() const { return Candidates.size(); }
diff --git a/include/llvm/CodeGen/MachinePassRegistry.h b/include/llvm/CodeGen/MachinePassRegistry.h
index a031c92d914f..f5b3723db0aa 100644
--- a/include/llvm/CodeGen/MachinePassRegistry.h
+++ b/include/llvm/CodeGen/MachinePassRegistry.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/MachinePassRegistry.h -----------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MachinePipeliner.h b/include/llvm/CodeGen/MachinePipeliner.h
index 38cb33e90e63..03ca53072685 100644
--- a/include/llvm/CodeGen/MachinePipeliner.h
+++ b/include/llvm/CodeGen/MachinePipeliner.h
@@ -1,9 +1,8 @@
//===- MachinePipeliner.h - Machine Software Pipeliner Pass -------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -63,6 +62,8 @@ public:
const InstrItineraryData *InstrItins;
const TargetInstrInfo *TII = nullptr;
RegisterClassInfo RegClassInfo;
+ bool disabledByPragma = false;
+ unsigned II_setByPragma = 0;
#ifndef NDEBUG
static int NumTries;
@@ -100,6 +101,7 @@ private:
bool canPipelineLoop(MachineLoop &L);
bool scheduleLoop(MachineLoop &L);
bool swingModuloScheduler(MachineLoop &L);
+ void setPragmaPipelineOptions(MachineLoop &L);
};
/// This class builds the dependence graph for the instructions in a loop,
@@ -108,11 +110,14 @@ class SwingSchedulerDAG : public ScheduleDAGInstrs {
MachinePipeliner &Pass;
/// The minimum initiation interval between iterations for this schedule.
unsigned MII = 0;
+ /// The maximum initiation interval between iterations for this schedule.
+ unsigned MAX_II = 0;
/// Set to true if a valid pipelined schedule is found for the loop.
bool Scheduled = false;
MachineLoop &Loop;
LiveIntervals &LIS;
const RegisterClassInfo &RegClassInfo;
+ unsigned II_setByPragma = 0;
/// A toplogical ordering of the SUnits, which is needed for changing
/// dependences and iterating over the SUnits.
@@ -190,9 +195,9 @@ class SwingSchedulerDAG : public ScheduleDAGInstrs {
public:
SwingSchedulerDAG(MachinePipeliner &P, MachineLoop &L, LiveIntervals &lis,
- const RegisterClassInfo &rci)
+ const RegisterClassInfo &rci, unsigned II)
: ScheduleDAGInstrs(*P.MF, P.MLI, false), Pass(P), Loop(L), LIS(lis),
- RegClassInfo(rci), Topo(SUnits, &ExitSU) {
+ RegClassInfo(rci), II_setByPragma(II), Topo(SUnits, &ExitSU) {
P.MF->getSubtarget().getSMSMutations(Mutations);
if (SwpEnableCopyToPhi)
Mutations.push_back(llvm::make_unique<CopyToPhiMutation>());
@@ -253,9 +258,6 @@ public:
return 0;
}
- /// Set the Minimum Initiation Interval for this schedule attempt.
- void setMII(unsigned mii) { MII = mii; }
-
void applyInstrChange(MachineInstr *MI, SMSchedule &Schedule);
void fixupRegisterOverlaps(std::deque<SUnit *> &Instrs);
@@ -316,9 +318,9 @@ private:
MBBVectorTy &EpilogBBs);
void splitLifetimes(MachineBasicBlock *KernelBB, MBBVectorTy &EpilogBBs,
SMSchedule &Schedule);
- void addBranches(MBBVectorTy &PrologBBs, MachineBasicBlock *KernelBB,
- MBBVectorTy &EpilogBBs, SMSchedule &Schedule,
- ValueMapTy *VRMap);
+ void addBranches(MachineBasicBlock &PreheaderBB, MBBVectorTy &PrologBBs,
+ MachineBasicBlock *KernelBB, MBBVectorTy &EpilogBBs,
+ SMSchedule &Schedule, ValueMapTy *VRMap);
bool computeDelta(MachineInstr &MI, unsigned &Delta);
void updateMemOperands(MachineInstr &NewMI, MachineInstr &OldMI,
unsigned Num);
@@ -346,6 +348,10 @@ private:
unsigned &OffsetPos, unsigned &NewBase,
int64_t &NewOffset);
void postprocessDAG();
+ /// Set the Minimum Initiation Interval for this schedule attempt.
+ void setMII(unsigned ResMII, unsigned RecMII);
+ /// Set the Maximum Initiation Interval for this schedule attempt.
+ void setMAX_II();
};
/// A NodeSet contains a set of SUnit DAG nodes with additional information
@@ -457,6 +463,56 @@ public:
#endif
};
+// 16 was selected based on the number of ProcResource kinds for all
+// existing Subtargets, so that SmallVector don't need to resize too often.
+static const int DefaultProcResSize = 16;
+
+class ResourceManager {
+private:
+ const MCSubtargetInfo *STI;
+ const MCSchedModel &SM;
+ const bool UseDFA;
+ std::unique_ptr<DFAPacketizer> DFAResources;
+ /// Each processor resource is associated with a so-called processor resource
+ /// mask. This vector allows to correlate processor resource IDs with
+ /// processor resource masks. There is exactly one element per each processor
+ /// resource declared by the scheduling model.
+ llvm::SmallVector<uint64_t, DefaultProcResSize> ProcResourceMasks;
+
+ llvm::SmallVector<uint64_t, DefaultProcResSize> ProcResourceCount;
+
+public:
+ ResourceManager(const TargetSubtargetInfo *ST)
+ : STI(ST), SM(ST->getSchedModel()), UseDFA(ST->useDFAforSMS()),
+ ProcResourceMasks(SM.getNumProcResourceKinds(), 0),
+ ProcResourceCount(SM.getNumProcResourceKinds(), 0) {
+ if (UseDFA)
+ DFAResources.reset(ST->getInstrInfo()->CreateTargetScheduleState(*ST));
+ initProcResourceVectors(SM, ProcResourceMasks);
+ }
+
+ void initProcResourceVectors(const MCSchedModel &SM,
+ SmallVectorImpl<uint64_t> &Masks);
+ /// Check if the resources occupied by a MCInstrDesc are available in
+ /// the current state.
+ bool canReserveResources(const MCInstrDesc *MID) const;
+
+ /// Reserve the resources occupied by a MCInstrDesc and change the current
+ /// state to reflect that change.
+ void reserveResources(const MCInstrDesc *MID);
+
+ /// Check if the resources occupied by a machine instruction are available
+ /// in the current state.
+ bool canReserveResources(const MachineInstr &MI) const;
+
+ /// Reserve the resources occupied by a machine instruction and change the
+ /// current state to reflect that change.
+ void reserveResources(const MachineInstr &MI);
+
+ /// Reset the state
+ void clearResources();
+};
+
/// This class represents the scheduled code. The main data structure is a
/// map from scheduled cycle to instructions. During scheduling, the
/// data structure explicitly represents all stages/iterations. When
@@ -495,12 +551,11 @@ private:
/// Virtual register information.
MachineRegisterInfo &MRI;
- std::unique_ptr<DFAPacketizer> Resources;
+ ResourceManager ProcItinResources;
public:
SMSchedule(MachineFunction *mf)
- : ST(mf->getSubtarget()), MRI(mf->getRegInfo()),
- Resources(ST.getInstrInfo()->CreateTargetScheduleState(ST)) {}
+ : ST(mf->getSubtarget()), MRI(mf->getRegInfo()), ProcItinResources(&ST) {}
void reset() {
ScheduledInstrs.clear();
diff --git a/include/llvm/CodeGen/MachinePostDominators.h b/include/llvm/CodeGen/MachinePostDominators.h
index c6a41598ce32..b67e6b52ac8f 100644
--- a/include/llvm/CodeGen/MachinePostDominators.h
+++ b/include/llvm/CodeGen/MachinePostDominators.h
@@ -1,9 +1,8 @@
-//=- llvm/CodeGen/MachineDominators.h ----------------------------*- C++ -*-==//
+//===- llvm/CodeGen/MachinePostDominators.h ----------------------*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MachineRegionInfo.h b/include/llvm/CodeGen/MachineRegionInfo.h
index 8394b58d0a16..6d9fb9b9100a 100644
--- a/include/llvm/CodeGen/MachineRegionInfo.h
+++ b/include/llvm/CodeGen/MachineRegionInfo.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/MachineRegionInfo.h -------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index fef010a23ef9..b5deed1f5010 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/MachineRegisterInfo.h -----------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -562,9 +561,14 @@ public:
}
/// hasOneNonDBGUse - Return true if there is exactly one non-Debug
- /// instruction using the specified register.
+ /// use of the specified register.
bool hasOneNonDBGUse(unsigned RegNo) const;
+ /// hasOneNonDBGUse - Return true if there is exactly one non-Debug
+ /// instruction using the specified register. Said instruction may have
+ /// multiple uses.
+ bool hasOneNonDBGUser(unsigned RegNo) const;
+
/// replaceRegWith - Replace all instances of FromReg with ToReg in the
/// machine function. This is like llvm-level X->replaceAllUsesWith(Y),
/// except that it also changes any definitions of the register as well.
@@ -713,12 +717,12 @@ public:
/// createVirtualRegister - Create and return a new virtual register in the
/// function with the specified register class.
- unsigned createVirtualRegister(const TargetRegisterClass *RegClass,
+ Register createVirtualRegister(const TargetRegisterClass *RegClass,
StringRef Name = "");
/// Create and return a new virtual register in the function with the same
/// attributes as the given register.
- unsigned cloneVirtualRegister(unsigned VReg, StringRef Name = "");
+ Register cloneVirtualRegister(Register VReg, StringRef Name = "");
/// Get the low-level type of \p Reg or LLT{} if Reg is not a generic
/// (target independent) virtual register.
@@ -733,7 +737,7 @@ public:
/// Create and return a new generic virtual register with low-level
/// type \p Ty.
- unsigned createGenericVirtualRegister(LLT Ty, StringRef Name = "");
+ Register createGenericVirtualRegister(LLT Ty, StringRef Name = "");
/// Remove all types associated to virtual registers (after instruction
/// selection and constraining of all generic virtual registers).
diff --git a/include/llvm/CodeGen/MachineSSAUpdater.h b/include/llvm/CodeGen/MachineSSAUpdater.h
index 5e91246b402c..0319ec774671 100644
--- a/include/llvm/CodeGen/MachineSSAUpdater.h
+++ b/include/llvm/CodeGen/MachineSSAUpdater.h
@@ -1,9 +1,8 @@
//===- MachineSSAUpdater.h - Unstructured SSA Update Tool -------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h
index 4bc31ae7c61a..75a334f61ad0 100644
--- a/include/llvm/CodeGen/MachineScheduler.h
+++ b/include/llvm/CodeGen/MachineScheduler.h
@@ -1,9 +1,8 @@
//===- MachineScheduler.h - MachineInstr Scheduling Pass --------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -265,10 +264,6 @@ protected:
LiveIntervals *LIS;
std::unique_ptr<MachineSchedStrategy> SchedImpl;
- /// Topo - A topological ordering for SUnits which permits fast IsReachable
- /// and similar queries.
- ScheduleDAGTopologicalSort Topo;
-
/// Ordered list of DAG postprocessing steps.
std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
@@ -292,7 +287,7 @@ public:
ScheduleDAGMI(MachineSchedContext *C, std::unique_ptr<MachineSchedStrategy> S,
bool RemoveKillFlags)
: ScheduleDAGInstrs(*C->MF, C->MLI, RemoveKillFlags), AA(C->AA),
- LIS(C->LIS), SchedImpl(std::move(S)), Topo(SUnits, &ExitSU) {}
+ LIS(C->LIS), SchedImpl(std::move(S)) {}
// Provide a vtable anchor
~ScheduleDAGMI() override;
@@ -320,17 +315,6 @@ public:
Mutations.push_back(std::move(Mutation));
}
- /// True if an edge can be added from PredSU to SuccSU without creating
- /// a cycle.
- bool canAddEdge(SUnit *SuccSU, SUnit *PredSU);
-
- /// Add a DAG edge to the given SU with the given predecessor
- /// dependence data.
- ///
- /// \returns true if the edge may be added without creating a cycle OR if an
- /// equivalent edge already existed (false indicates failure).
- bool addEdge(SUnit *SuccSU, const SDep &PredDep);
-
MachineBasicBlock::iterator top() const { return CurrentTop; }
MachineBasicBlock::iterator bottom() const { return CurrentBottom; }
@@ -682,6 +666,10 @@ private:
// scheduled instruction.
SmallVector<unsigned, 16> ReservedCycles;
+ // For each PIdx, stores first index into ReservedCycles that corresponds to
+ // it.
+ SmallVector<unsigned, 16> ReservedCyclesIndex;
+
#ifndef NDEBUG
// Remember the greatest possible stall as an upper bound on the number of
// times we should retry the pending queue because of a hazard.
@@ -756,7 +744,11 @@ public:
/// cycle.
unsigned getLatencyStallCycles(SUnit *SU);
- unsigned getNextResourceCycle(unsigned PIdx, unsigned Cycles);
+ unsigned getNextResourceCycleByInstance(unsigned InstanceIndex,
+ unsigned Cycles);
+
+ std::pair<unsigned, unsigned> getNextResourceCycle(unsigned PIdx,
+ unsigned Cycles);
bool checkHazard(SUnit *SU);
@@ -1015,6 +1007,7 @@ protected:
/// Callbacks from ScheduleDAGMI:
/// initPolicy -> initialize(DAG) -> registerRoots -> pickNode ...
class PostGenericScheduler : public GenericSchedulerBase {
+protected:
ScheduleDAGMI *DAG;
SchedBoundary Top;
SmallVector<SUnit*, 8> BotRoots;
diff --git a/include/llvm/CodeGen/MachineTraceMetrics.h b/include/llvm/CodeGen/MachineTraceMetrics.h
index 9d8db393ca92..025989504177 100644
--- a/include/llvm/CodeGen/MachineTraceMetrics.h
+++ b/include/llvm/CodeGen/MachineTraceMetrics.h
@@ -1,9 +1,8 @@
//===- lib/CodeGen/MachineTraceMetrics.h - Super-scalar metrics -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/MacroFusion.h b/include/llvm/CodeGen/MacroFusion.h
index a77226ddaf33..3a140fe63fde 100644
--- a/include/llvm/CodeGen/MacroFusion.h
+++ b/include/llvm/CodeGen/MacroFusion.h
@@ -1,9 +1,8 @@
//===- MacroFusion.h - Macro Fusion -----------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/PBQP/CostAllocator.h b/include/llvm/CodeGen/PBQP/CostAllocator.h
index bde451ae1fcc..0d6d8a31317b 100644
--- a/include/llvm/CodeGen/PBQP/CostAllocator.h
+++ b/include/llvm/CodeGen/PBQP/CostAllocator.h
@@ -1,9 +1,8 @@
//===- CostAllocator.h - PBQP Cost Allocator --------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/PBQP/Graph.h b/include/llvm/CodeGen/PBQP/Graph.h
index a6d88b057dcb..c2cd6dadae5f 100644
--- a/include/llvm/CodeGen/PBQP/Graph.h
+++ b/include/llvm/CodeGen/PBQP/Graph.h
@@ -1,9 +1,8 @@
//===- Graph.h - PBQP Graph -------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/PBQP/Math.h b/include/llvm/CodeGen/PBQP/Math.h
index d1432a3053c4..8b014ccbb07b 100644
--- a/include/llvm/CodeGen/PBQP/Math.h
+++ b/include/llvm/CodeGen/PBQP/Math.h
@@ -1,9 +1,8 @@
//===- Math.h - PBQP Vector and Matrix classes ------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/PBQP/ReductionRules.h b/include/llvm/CodeGen/PBQP/ReductionRules.h
index 21b99027970d..51822d082bad 100644
--- a/include/llvm/CodeGen/PBQP/ReductionRules.h
+++ b/include/llvm/CodeGen/PBQP/ReductionRules.h
@@ -1,9 +1,8 @@
//===- ReductionRules.h - Reduction Rules -----------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/PBQP/Solution.h b/include/llvm/CodeGen/PBQP/Solution.h
index 4d4379fbc2c2..d5b1474f0f4c 100644
--- a/include/llvm/CodeGen/PBQP/Solution.h
+++ b/include/llvm/CodeGen/PBQP/Solution.h
@@ -1,9 +1,8 @@
//===- Solution.h - PBQP Solution -------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/PBQPRAConstraint.h b/include/llvm/CodeGen/PBQPRAConstraint.h
index 995467dc56d8..876ab97a669f 100644
--- a/include/llvm/CodeGen/PBQPRAConstraint.h
+++ b/include/llvm/CodeGen/PBQPRAConstraint.h
@@ -1,9 +1,8 @@
-//===- RegAllocPBQP.h -------------------------------------------*- C++ -*-===//
+//===- llvm/CodeGen/PBQPRAConstraint.h --------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/ParallelCG.h b/include/llvm/CodeGen/ParallelCG.h
index dbf09ea31e20..a44715d4fc4f 100644
--- a/include/llvm/CodeGen/ParallelCG.h
+++ b/include/llvm/CodeGen/ParallelCG.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/ParallelCG.h - Parallel code generation ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index acf1ebb5bc83..d92ee93268e7 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -1,9 +1,8 @@
//===-- Passes.h - Target independent code generation passes ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -346,8 +345,9 @@ namespace llvm {
/// pointer or stack pointer index addressing.
extern char &LocalStackSlotAllocationID;
- /// ExpandISelPseudos - This pass expands pseudo-instructions.
- extern char &ExpandISelPseudosID;
+ /// This pass expands pseudo-instructions, reserves registers and adjusts
+ /// machine frame information.
+ extern char &FinalizeISelID;
/// UnpackMachineBundles - This pass unpack machine instruction bundles.
extern char &UnpackMachineBundlesID;
@@ -447,6 +447,9 @@ namespace llvm {
/// Creates CFI Instruction Inserter pass. \see CFIInstrInserter.cpp
FunctionPass *createCFIInstrInserter();
+ /// Create Hardware Loop pass. \see HardwareLoops.cpp
+ FunctionPass *createHardwareLoopsPass();
+
} // End llvm namespace
#endif
diff --git a/include/llvm/CodeGen/PreISelIntrinsicLowering.h b/include/llvm/CodeGen/PreISelIntrinsicLowering.h
index b7f83e515b7e..73d7d779e55b 100644
--- a/include/llvm/CodeGen/PreISelIntrinsicLowering.h
+++ b/include/llvm/CodeGen/PreISelIntrinsicLowering.h
@@ -1,9 +1,8 @@
//===- PreISelIntrinsicLowering.h - Pre-ISel intrinsic lowering pass ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/PseudoSourceValue.h b/include/llvm/CodeGen/PseudoSourceValue.h
index f66191bc9fb4..4b3cc9145a13 100644
--- a/include/llvm/CodeGen/PseudoSourceValue.h
+++ b/include/llvm/CodeGen/PseudoSourceValue.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/PseudoSourceValue.h ------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -16,7 +15,6 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/IR/GlobalValue.h"
-#include "llvm/IR/Value.h"
#include "llvm/IR/ValueMap.h"
#include <map>
@@ -124,7 +122,7 @@ public:
bool mayAlias(const MachineFrameInfo *) const override;
};
-/// A specialized pseudo soruce value for holding GlobalValue values.
+/// A specialized pseudo source value for holding GlobalValue values.
class GlobalValuePseudoSourceValue : public CallEntryPseudoSourceValue {
const GlobalValue *GV;
diff --git a/include/llvm/CodeGen/ReachingDefAnalysis.h b/include/llvm/CodeGen/ReachingDefAnalysis.h
index b21b745c8fd1..a599fb62f5e2 100644
--- a/include/llvm/CodeGen/ReachingDefAnalysis.h
+++ b/include/llvm/CodeGen/ReachingDefAnalysis.h
@@ -1,15 +1,14 @@
//==--- llvm/CodeGen/ReachingDefAnalysis.h - Reaching Def Analysis -*- C++ -*---==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
/// \file Reaching Defs Analysis pass.
///
-/// This pass tracks for each instruction what is the “closest” reaching def of
+/// This pass tracks for each instruction what is the "closest" reaching def of
/// a given register. It is used by BreakFalseDeps (for clearance calculation)
/// and ExecutionDomainFix (for arbitrating conflicting domains).
///
diff --git a/include/llvm/CodeGen/RegAllocPBQP.h b/include/llvm/CodeGen/RegAllocPBQP.h
index ba9763077d09..f7f92248f4ce 100644
--- a/include/llvm/CodeGen/RegAllocPBQP.h
+++ b/include/llvm/CodeGen/RegAllocPBQP.h
@@ -1,9 +1,8 @@
//===- RegAllocPBQP.h -------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/RegAllocRegistry.h b/include/llvm/CodeGen/RegAllocRegistry.h
index b518fbb9c9da..9a63674689b3 100644
--- a/include/llvm/CodeGen/RegAllocRegistry.h
+++ b/include/llvm/CodeGen/RegAllocRegistry.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/RegAllocRegistry.h --------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -23,29 +22,30 @@ class FunctionPass;
//===----------------------------------------------------------------------===//
///
-/// RegisterRegAlloc class - Track the registration of register allocators.
+/// RegisterRegAllocBase class - Track the registration of register allocators.
///
//===----------------------------------------------------------------------===//
-class RegisterRegAlloc : public MachinePassRegistryNode<FunctionPass *(*)()> {
+template <class SubClass>
+class RegisterRegAllocBase : public MachinePassRegistryNode<FunctionPass *(*)()> {
public:
using FunctionPassCtor = FunctionPass *(*)();
static MachinePassRegistry<FunctionPassCtor> Registry;
- RegisterRegAlloc(const char *N, const char *D, FunctionPassCtor C)
+ RegisterRegAllocBase(const char *N, const char *D, FunctionPassCtor C)
: MachinePassRegistryNode(N, D, C) {
Registry.Add(this);
}
- ~RegisterRegAlloc() { Registry.Remove(this); }
+ ~RegisterRegAllocBase() { Registry.Remove(this); }
// Accessors.
- RegisterRegAlloc *getNext() const {
- return (RegisterRegAlloc *)MachinePassRegistryNode::getNext();
+ SubClass *getNext() const {
+ return static_cast<SubClass *>(MachinePassRegistryNode::getNext());
}
- static RegisterRegAlloc *getList() {
- return (RegisterRegAlloc *)Registry.getList();
+ static SubClass *getList() {
+ return static_cast<SubClass *>(Registry.getList());
}
static FunctionPassCtor getDefault() { return Registry.getDefault(); }
@@ -57,6 +57,17 @@ public:
}
};
+class RegisterRegAlloc : public RegisterRegAllocBase<RegisterRegAlloc> {
+public:
+ RegisterRegAlloc(const char *N, const char *D, FunctionPassCtor C)
+ : RegisterRegAllocBase(N, D, C) {}
+};
+
+/// RegisterRegAlloc's global Registry tracks allocator registration.
+template <class T>
+MachinePassRegistry<RegisterRegAlloc::FunctionPassCtor>
+RegisterRegAllocBase<T>::Registry;
+
} // end namespace llvm
#endif // LLVM_CODEGEN_REGALLOCREGISTRY_H
diff --git a/include/llvm/CodeGen/Register.h b/include/llvm/CodeGen/Register.h
new file mode 100644
index 000000000000..907c1a99e56f
--- /dev/null
+++ b/include/llvm/CodeGen/Register.h
@@ -0,0 +1,60 @@
+//===-- llvm/CodeGen/Register.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_REGISTER_H
+#define LLVM_CODEGEN_REGISTER_H
+
+#include <cassert>
+
+namespace llvm {
+
+/// Wrapper class representing virtual and physical registers. Should be passed
+/// by value.
+class Register {
+ unsigned Reg;
+
+public:
+ Register(unsigned Val = 0): Reg(Val) {}
+
+ /// Return true if the specified register number is in the virtual register
+ /// namespace.
+ bool isVirtual() const {
+ return int(Reg) < 0;
+ }
+
+ /// Return true if the specified register number is in the physical register
+ /// namespace.
+ bool isPhysical() const {
+ return int(Reg) > 0;
+ }
+
+ /// Convert a virtual register number to a 0-based index. The first virtual
+ /// register in a function will get the index 0.
+ unsigned virtRegIndex() const {
+ assert(isVirtual() && "Not a virtual register");
+ return Reg & ~(1u << 31);
+ }
+
+ /// Convert a 0-based index to a virtual register number.
+ /// This is the inverse operation of VirtReg2IndexFunctor below.
+ static Register index2VirtReg(unsigned Index) {
+ return Register(Index | (1u << 31));
+ }
+
+ operator unsigned() const {
+ return Reg;
+ }
+
+ bool isValid() const {
+ return Reg != 0;
+ }
+};
+
+}
+
+#endif
diff --git a/include/llvm/CodeGen/RegisterClassInfo.h b/include/llvm/CodeGen/RegisterClassInfo.h
index 97113c575815..14af5c4d090d 100644
--- a/include/llvm/CodeGen/RegisterClassInfo.h
+++ b/include/llvm/CodeGen/RegisterClassInfo.h
@@ -1,9 +1,8 @@
//===- RegisterClassInfo.h - Dynamic Register Class Info --------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/RegisterPressure.h b/include/llvm/CodeGen/RegisterPressure.h
index 79054b9e33b7..5bbaa03fd751 100644
--- a/include/llvm/CodeGen/RegisterPressure.h
+++ b/include/llvm/CodeGen/RegisterPressure.h
@@ -1,9 +1,8 @@
//===- RegisterPressure.h - Dynamic Register Pressure -----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -132,10 +131,6 @@ public:
}
};
-template <> struct isPodLike<PressureChange> {
- static const bool value = true;
-};
-
/// List of PressureChanges in order of increasing, unique PSetID.
///
/// Use a small fixed number, because we can fit more PressureChanges in an
diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h
index b6bd028a8cac..9c48df82f07d 100644
--- a/include/llvm/CodeGen/RegisterScavenging.h
+++ b/include/llvm/CodeGen/RegisterScavenging.h
@@ -1,9 +1,8 @@
//===- RegisterScavenging.h - Machine register scavenging -------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -158,10 +157,15 @@ public:
/// Returns the scavenged register.
/// This is deprecated as it depends on the quality of the kill flags being
/// present; Use scavengeRegisterBackwards() instead!
+ ///
+ /// If \p AllowSpill is false, fail if a spill is required to make the
+ /// register available, and return NoRegister.
unsigned scavengeRegister(const TargetRegisterClass *RC,
- MachineBasicBlock::iterator I, int SPAdj);
- unsigned scavengeRegister(const TargetRegisterClass *RegClass, int SPAdj) {
- return scavengeRegister(RegClass, MBBI, SPAdj);
+ MachineBasicBlock::iterator I, int SPAdj,
+ bool AllowSpill = true);
+ unsigned scavengeRegister(const TargetRegisterClass *RegClass, int SPAdj,
+ bool AllowSpill = true) {
+ return scavengeRegister(RegClass, MBBI, SPAdj, AllowSpill);
}
/// Make a register of the specific register class available from the current
@@ -170,9 +174,13 @@ public:
/// SPAdj is the stack adjustment due to call frame, it's passed along to
/// eliminateFrameIndex().
/// Returns the scavenged register.
+ ///
+ /// If \p AllowSpill is false, fail if a spill is required to make the
+ /// register available, and return NoRegister.
unsigned scavengeRegisterBackwards(const TargetRegisterClass &RC,
MachineBasicBlock::iterator To,
- bool RestoreAfter, int SPAdj);
+ bool RestoreAfter, int SPAdj,
+ bool AllowSpill = true);
/// Tell the scavenger a register is used.
void setRegUsed(unsigned Reg, LaneBitmask LaneMask = LaneBitmask::getAll());
diff --git a/include/llvm/CodeGen/RegisterUsageInfo.h b/include/llvm/CodeGen/RegisterUsageInfo.h
index efecc61d9c30..33554550b9dc 100644
--- a/include/llvm/CodeGen/RegisterUsageInfo.h
+++ b/include/llvm/CodeGen/RegisterUsageInfo.h
@@ -1,9 +1,8 @@
//==- RegisterUsageInfo.h - Register Usage Informartion Storage --*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
diff --git a/include/llvm/CodeGen/ResourcePriorityQueue.h b/include/llvm/CodeGen/ResourcePriorityQueue.h
index 8d582ee298b6..81587a3170ce 100644
--- a/include/llvm/CodeGen/ResourcePriorityQueue.h
+++ b/include/llvm/CodeGen/ResourcePriorityQueue.h
@@ -1,9 +1,8 @@
//===----- ResourcePriorityQueue.h - A DFA-oriented priority queue -------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h
index 28567a1ce437..f71f39e5bf03 100644
--- a/include/llvm/CodeGen/RuntimeLibcalls.h
+++ b/include/llvm/CodeGen/RuntimeLibcalls.h
@@ -1,9 +1,8 @@
//===-- CodeGen/RuntimeLibcalls.h - Runtime Library Calls -------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/SDNodeProperties.td b/include/llvm/CodeGen/SDNodeProperties.td
index 83bbab2fdc8d..d25e0bda26a9 100644
--- a/include/llvm/CodeGen/SDNodeProperties.td
+++ b/include/llvm/CodeGen/SDNodeProperties.td
@@ -1,9 +1,8 @@
//===- SDNodeProperties.td - Common code for DAG isels ---*- tablegen -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
index 0870d67db390..e004f3bf2cc1 100644
--- a/include/llvm/CodeGen/ScheduleDAG.h
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/ScheduleDAG.h - Common Base Class -----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -239,9 +238,6 @@ class TargetRegisterInfo;
void dump(const TargetRegisterInfo *TRI = nullptr) const;
};
- template <>
- struct isPodLike<SDep> { static const bool value = true; };
-
/// Scheduling unit. This is a node in the scheduling DAG.
class SUnit {
private:
@@ -418,7 +414,7 @@ class TargetRegisterInfo;
/// dirty.
void setDepthToAtLeast(unsigned NewDepth);
- /// If NewDepth is greater than this node's depth value, set it to be
+ /// If NewHeight is greater than this node's height value, set it to be
/// the new height value. This also recursively marks predecessor nodes
/// dirty.
void setHeightToAtLeast(unsigned NewHeight);
@@ -695,6 +691,12 @@ class TargetRegisterInfo;
std::vector<SUnit> &SUnits;
SUnit *ExitSU;
+ // Have any new nodes been added?
+ bool Dirty = false;
+
+ // Outstanding added edges, that have not been applied to the ordering.
+ SmallVector<std::pair<SUnit *, SUnit *>, 16> Updates;
+
/// Maps topological index to the node number.
std::vector<int> Index2Node;
/// Maps the node number to its topological index.
@@ -714,6 +716,11 @@ class TargetRegisterInfo;
/// Assigns the topological index to the node n.
void Allocate(int n, int index);
+ /// Fix the ordering, by either recomputing from scratch or by applying
+ /// any outstanding updates. Uses a heuristic to estimate what will be
+ /// cheaper.
+ void FixOrder();
+
public:
ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits, SUnit *ExitSU);
@@ -738,11 +745,19 @@ class TargetRegisterInfo;
/// added from SUnit \p X to SUnit \p Y.
void AddPred(SUnit *Y, SUnit *X);
+ /// Queues an update to the topological ordering to accommodate an edge to
+ /// be added from SUnit \p X to SUnit \p Y.
+ void AddPredQueued(SUnit *Y, SUnit *X);
+
/// Updates the topological ordering to accommodate an an edge to be
/// removed from the specified node \p N from the predecessors of the
/// current node \p M.
void RemovePred(SUnit *M, SUnit *N);
+ /// Mark the ordering as temporarily broken, after a new node has been
+ /// added.
+ void MarkDirty() { Dirty = true; }
+
typedef std::vector<int>::iterator iterator;
typedef std::vector<int>::const_iterator const_iterator;
iterator begin() { return Index2Node.begin(); }
diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h
index daad18125db9..3e3b604acbac 100644
--- a/include/llvm/CodeGen/ScheduleDAGInstrs.h
+++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -1,9 +1,8 @@
//===- ScheduleDAGInstrs.h - MachineInstr Scheduling ------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -235,6 +234,11 @@ namespace llvm {
/// For an unanalyzable memory access, this Value is used in maps.
UndefValue *UnknownValue;
+
+ /// Topo - A topological ordering for SUnits which permits fast IsReachable
+ /// and similar queries.
+ ScheduleDAGTopologicalSort Topo;
+
using DbgValueVector =
std::vector<std::pair<MachineInstr *, MachineInstr *>>;
/// Remember instruction that precedes DBG_VALUE.
@@ -339,6 +343,17 @@ namespace llvm {
/// Fixes register kill flags that scheduling has made invalid.
void fixupKills(MachineBasicBlock &MBB);
+ /// True if an edge can be added from PredSU to SuccSU without creating
+ /// a cycle.
+ bool canAddEdge(SUnit *SuccSU, SUnit *PredSU);
+
+ /// Add a DAG edge to the given SU with the given predecessor
+ /// dependence data.
+ ///
+ /// \returns true if the edge may be added without creating a cycle OR if an
+ /// equivalent edge already existed (false indicates failure).
+ bool addEdge(SUnit *SuccSU, const SDep &PredDep);
+
protected:
void initSUnits();
void addPhysRegDataDeps(SUnit *SU, unsigned OperIdx);
diff --git a/include/llvm/CodeGen/ScheduleDAGMutation.h b/include/llvm/CodeGen/ScheduleDAGMutation.h
index 5c236427e0b8..d1dd72859a38 100644
--- a/include/llvm/CodeGen/ScheduleDAGMutation.h
+++ b/include/llvm/CodeGen/ScheduleDAGMutation.h
@@ -1,9 +1,8 @@
//===- ScheduleDAGMutation.h - MachineInstr Scheduling ----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/ScheduleDFS.h b/include/llvm/CodeGen/ScheduleDFS.h
index 3ecc033ac35a..d60deab95f5d 100644
--- a/include/llvm/CodeGen/ScheduleDFS.h
+++ b/include/llvm/CodeGen/ScheduleDFS.h
@@ -1,9 +1,8 @@
-//===- ScheduleDAGILP.h - ILP metric for ScheduleDAGInstrs ------*- C++ -*-===//
+//===- ScheduleDFS.h - ILP metric for ScheduleDAGInstrs ---------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/ScheduleHazardRecognizer.h b/include/llvm/CodeGen/ScheduleHazardRecognizer.h
index ace4a2d836ca..37590f496ca2 100644
--- a/include/llvm/CodeGen/ScheduleHazardRecognizer.h
+++ b/include/llvm/CodeGen/ScheduleHazardRecognizer.h
@@ -1,9 +1,8 @@
//=- llvm/CodeGen/ScheduleHazardRecognizer.h - Scheduling Support -*- C++ -*-=//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/SchedulerRegistry.h b/include/llvm/CodeGen/SchedulerRegistry.h
index fbe559f25556..0ccfaafd9e50 100644
--- a/include/llvm/CodeGen/SchedulerRegistry.h
+++ b/include/llvm/CodeGen/SchedulerRegistry.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/SchedulerRegistry.h -------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
index 3f75d108f282..ac67f3008fa7 100644
--- a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
+++ b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
@@ -1,9 +1,8 @@
//=- llvm/CodeGen/ScoreboardHazardRecognizer.h - Schedule Support -*- C++ -*-=//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index 67fe87fc96af..12a970847021 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/SelectionDAG.h - InstSelection DAG ----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -268,6 +267,10 @@ class SelectionDAG {
/// Tracks dbg_value and dbg_label information through SDISel.
SDDbgInfo *DbgInfo;
+ using CallSiteInfo = MachineFunction::CallSiteInfo;
+ using CallSiteInfoImpl = MachineFunction::CallSiteInfoImpl;
+ DenseMap<const SDNode *, CallSiteInfo> SDCallSiteInfo;
+
uint16_t NextPersistentId = 0;
public:
@@ -298,6 +301,9 @@ public:
/// The node N that was updated.
virtual void NodeUpdated(SDNode *N);
+
+ /// The node N that was inserted.
+ virtual void NodeInserted(SDNode *N);
};
struct DAGNodeDeletedListener : public DAGUpdateListener {
@@ -404,6 +410,7 @@ public:
const TargetLowering &getTargetLoweringInfo() const { return *TLI; }
const TargetLibraryInfo &getLibInfo() const { return *LibInfo; }
const SelectionDAGTargetInfo &getSelectionDAGInfo() const { return *TSI; }
+ const LegacyDivergenceAnalysis *getDivergenceAnalysis() const { return DA; }
LLVMContext *getContext() const {return Context; }
OptimizationRemarkEmitter &getORE() const { return *ORE; }
@@ -573,6 +580,9 @@ public:
bool isTarget = false, bool isOpaque = false);
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL,
bool isTarget = false);
+ SDValue getShiftAmountConstant(uint64_t Val, EVT VT, const SDLoc &DL,
+ bool LegalTypes = true);
+
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT,
bool isOpaque = false) {
return getConstant(Val, DL, VT, true, isOpaque);
@@ -789,6 +799,16 @@ public:
/// value assuming it was the smaller SrcTy value.
SDValue getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT VT);
+ /// Convert Op, which must be of integer type, to the integer type VT, by
+ /// either truncating it or performing either zero or sign extension as
+ /// appropriate extension for the pointer's semantics.
+ SDValue getPtrExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT);
+
+ /// Return the expression required to extend the Op as a pointer value
+ /// assuming it was the smaller SrcTy value. This may be either a zero extend
+ /// or a sign extend.
+ SDValue getPtrExtendInReg(SDValue Op, const SDLoc &DL, EVT VT);
+
/// Convert Op, which must be of integer type, to the integer type VT,
/// by using an extension appropriate for the target's
/// BooleanContent for type OpVT or truncating it.
@@ -971,6 +991,10 @@ public:
/// Try to simplify a shift into 1 of its operands or a constant.
SDValue simplifyShift(SDValue X, SDValue Y);
+ /// Try to simplify a floating-point binary operation into 1 of its operands
+ /// or a constant.
+ SDValue simplifyFPBinop(unsigned Opcode, SDValue X, SDValue Y);
+
/// VAArg produces a result and token chain, and takes a pointer
/// and a source value as input.
SDValue getVAArg(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr,
@@ -982,21 +1006,11 @@ public:
/// a success flag (initially i1), and a chain.
SDValue getAtomicCmpSwap(unsigned Opcode, const SDLoc &dl, EVT MemVT,
SDVTList VTs, SDValue Chain, SDValue Ptr,
- SDValue Cmp, SDValue Swp, MachinePointerInfo PtrInfo,
- unsigned Alignment, AtomicOrdering SuccessOrdering,
- AtomicOrdering FailureOrdering,
- SyncScope::ID SSID);
- SDValue getAtomicCmpSwap(unsigned Opcode, const SDLoc &dl, EVT MemVT,
- SDVTList VTs, SDValue Chain, SDValue Ptr,
SDValue Cmp, SDValue Swp, MachineMemOperand *MMO);
/// Gets a node for an atomic op, produces result (if relevant)
/// and chain and takes 2 operands.
SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain,
- SDValue Ptr, SDValue Val, const Value *PtrVal,
- unsigned Alignment, AtomicOrdering Ordering,
- SyncScope::ID SSID);
- SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain,
SDValue Ptr, SDValue Val, MachineMemOperand *MMO);
/// Gets a node for an atomic op, produces result and chain and
@@ -1021,12 +1035,19 @@ public:
unsigned Align = 0,
MachineMemOperand::Flags Flags
= MachineMemOperand::MOLoad | MachineMemOperand::MOStore,
- unsigned Size = 0);
+ unsigned Size = 0,
+ const AAMDNodes &AAInfo = AAMDNodes());
SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList,
ArrayRef<SDValue> Ops, EVT MemVT,
MachineMemOperand *MMO);
+ /// Creates a LifetimeSDNode that starts (`IsStart==true`) or ends
+ /// (`IsStart==false`) the lifetime of the portion of `FrameIndex` between
+ /// offsets `Offset` and `Offset + Size`.
+ SDValue getLifetimeNode(bool IsStart, const SDLoc &dl, SDValue Chain,
+ int FrameIndex, int64_t Size, int64_t Offset = -1);
+
/// Create a MERGE_VALUES node from the given operands.
SDValue getMergeValues(ArrayRef<SDValue> Ops, const SDLoc &dl);
@@ -1154,6 +1175,11 @@ public:
SDValue Op3, SDValue Op4, SDValue Op5);
SDNode *UpdateNodeOperands(SDNode *N, ArrayRef<SDValue> Ops);
+ /// Creates a new TokenFactor containing \p Vals. If \p Vals contains 64k
+ /// values or more, move values into new TokenFactors in 64k-1 blocks, until
+ /// the final TokenFactor has less than 64k operands.
+ SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl<SDValue> &Vals);
+
/// *Mutate* the specified machine node's memory references to the provided
/// list.
void setNodeMemRefs(MachineSDNode *N,
@@ -1358,21 +1384,20 @@ public:
/// with this SelectionDAG.
bool hasDebugValues() const { return !DbgInfo->empty(); }
- SDDbgInfo::DbgIterator DbgBegin() { return DbgInfo->DbgBegin(); }
- SDDbgInfo::DbgIterator DbgEnd() { return DbgInfo->DbgEnd(); }
+ SDDbgInfo::DbgIterator DbgBegin() const { return DbgInfo->DbgBegin(); }
+ SDDbgInfo::DbgIterator DbgEnd() const { return DbgInfo->DbgEnd(); }
- SDDbgInfo::DbgIterator ByvalParmDbgBegin() {
+ SDDbgInfo::DbgIterator ByvalParmDbgBegin() const {
return DbgInfo->ByvalParmDbgBegin();
}
-
- SDDbgInfo::DbgIterator ByvalParmDbgEnd() {
+ SDDbgInfo::DbgIterator ByvalParmDbgEnd() const {
return DbgInfo->ByvalParmDbgEnd();
}
- SDDbgInfo::DbgLabelIterator DbgLabelBegin() {
+ SDDbgInfo::DbgLabelIterator DbgLabelBegin() const {
return DbgInfo->DbgLabelBegin();
}
- SDDbgInfo::DbgLabelIterator DbgLabelEnd() {
+ SDDbgInfo::DbgLabelIterator DbgLabelEnd() const {
return DbgInfo->DbgLabelEnd();
}
@@ -1395,27 +1420,42 @@ public:
const SDNode *N2);
SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT,
- SDNode *Cst1, SDNode *Cst2);
+ SDNode *N1, SDNode *N2);
SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT,
- const ConstantSDNode *Cst1,
- const ConstantSDNode *Cst2);
+ const ConstantSDNode *C1,
+ const ConstantSDNode *C2);
SDValue FoldConstantVectorArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT,
ArrayRef<SDValue> Ops,
const SDNodeFlags Flags = SDNodeFlags());
+ /// Fold floating-point operations with 2 operands when both operands are
+ /// constants and/or undefined.
+ SDValue foldConstantFPMath(unsigned Opcode, const SDLoc &DL, EVT VT,
+ SDValue N1, SDValue N2);
+
/// Constant fold a setcc to true or false.
SDValue FoldSetCC(EVT VT, SDValue N1, SDValue N2, ISD::CondCode Cond,
const SDLoc &dl);
- /// See if the specified operand can be simplified with the knowledge that only
- /// the bits specified by Mask are used. If so, return the simpler operand,
- /// otherwise return a null SDValue.
+ /// See if the specified operand can be simplified with the knowledge that
+ /// only the bits specified by DemandedBits are used. If so, return the
+ /// simpler operand, otherwise return a null SDValue.
+ ///
+ /// (This exists alongside SimplifyDemandedBits because GetDemandedBits can
+ /// simplify nodes with multiple uses more aggressively.)
+ SDValue GetDemandedBits(SDValue V, const APInt &DemandedBits);
+
+ /// See if the specified operand can be simplified with the knowledge that
+ /// only the bits specified by DemandedBits are used in the elements specified
+ /// by DemandedElts. If so, return the simpler operand, otherwise return a
+ /// null SDValue.
///
/// (This exists alongside SimplifyDemandedBits because GetDemandedBits can
/// simplify nodes with multiple uses more aggressively.)
- SDValue GetDemandedBits(SDValue V, const APInt &Mask);
+ SDValue GetDemandedBits(SDValue V, const APInt &DemandedBits,
+ const APInt &DemandedElts);
/// Return true if the sign bit of Op is known to be zero.
/// We use this predicate to simplify operations downstream.
@@ -1424,8 +1464,19 @@ public:
/// Return true if 'Op & Mask' is known to be zero. We
/// use this predicate to simplify operations downstream. Op and Mask are
/// known to be the same type.
- bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth = 0)
- const;
+ bool MaskedValueIsZero(SDValue Op, const APInt &Mask,
+ unsigned Depth = 0) const;
+
+ /// Return true if 'Op & Mask' is known to be zero in DemandedElts. We
+ /// use this predicate to simplify operations downstream. Op and Mask are
+ /// known to be the same type.
+ bool MaskedValueIsZero(SDValue Op, const APInt &Mask,
+ const APInt &DemandedElts, unsigned Depth = 0) const;
+
+ /// Return true if '(Op & Mask) == Mask'.
+ /// Op and Mask are known to be the same type.
+ bool MaskedValueIsAllOnes(SDValue Op, const APInt &Mask,
+ unsigned Depth = 0) const;
/// Determine which bits of Op are known to be either zero or one and return
/// them in Known. For vectors, the known bits are those that are shared by
@@ -1525,6 +1576,13 @@ public:
/// Test whether \p V has a splatted value.
bool isSplatValue(SDValue V, bool AllowUndefs = false);
+ /// If V is a splatted value, return the source vector and its splat index.
+ SDValue getSplatSourceVector(SDValue V, int &SplatIndex);
+
+ /// If V is a splat vector, return its scalar source operand by extracting
+ /// that element from the source vector.
+ SDValue getSplatValue(SDValue V);
+
/// Match a binop + shuffle pyramid that represents a horizontal reduction
/// over the elements of a vector starting from the EXTRACT_VECTOR_ELT node /p
/// Extract. The reduction must use one of the opcodes listed in /p
@@ -1542,6 +1600,11 @@ public:
/// vector op and fill the end of the resulting vector with UNDEFS.
SDValue UnrollVectorOp(SDNode *N, unsigned ResNE = 0);
+ /// Like UnrollVectorOp(), but for the [US](ADD|SUB|MUL)O family of opcodes.
+ /// This is a separate function because those opcodes have two results.
+ std::pair<SDValue, SDValue> UnrollVectorOverflowOp(SDNode *N,
+ unsigned ResNE = 0);
+
/// Return true if loads are next to each other and can be
/// merged. Check that both are nonvolatile and if LD is loading
/// 'Bytes' bytes from a location that is 'Dist' units away from the
@@ -1576,6 +1639,9 @@ public:
return SplitVector(N->getOperand(OpNo), SDLoc(N));
}
+ /// Widen the vector up to the next power of two using INSERT_SUBVECTOR.
+ SDValue WidenVector(const SDValue &N, const SDLoc &DL);
+
/// Append the extracted elements from Start to Count out of the vector Op
/// in Args. If Count is 0, all of the elements will be extracted.
void ExtractVectorElements(SDValue Op, SmallVectorImpl<SDValue> &Args,
@@ -1597,6 +1663,17 @@ public:
isConstantFPBuildVectorOrConstantFP(N);
}
+ void addCallSiteInfo(const SDNode *CallNode, CallSiteInfoImpl &&CallInfo) {
+ SDCallSiteInfo[CallNode] = std::move(CallInfo);
+ }
+
+ CallSiteInfo getSDCallSiteInfo(const SDNode *CallNode) {
+ auto I = SDCallSiteInfo.find(CallNode);
+ if (I != SDCallSiteInfo.end())
+ return std::move(I->second);
+ return CallSiteInfo();
+ }
+
private:
void InsertNode(SDNode *N);
bool RemoveNodeFromCSEMaps(SDNode *N);
diff --git a/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h b/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h
index 2b2c48d57bc0..4ee58333495b 100644
--- a/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h
+++ b/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h
@@ -1,9 +1,8 @@
//===- SelectionDAGAddressAnalysis.h - DAG Address Analysis -----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -34,11 +33,13 @@ class BaseIndexOffset {
private:
SDValue Base;
SDValue Index;
- int64_t Offset = 0;
+ Optional<int64_t> Offset;
bool IsIndexSignExt = false;
public:
BaseIndexOffset() = default;
+ BaseIndexOffset(SDValue Base, SDValue Index, bool IsIndexSignExt)
+ : Base(Base), Index(Index), Offset(), IsIndexSignExt(IsIndexSignExt) {}
BaseIndexOffset(SDValue Base, SDValue Index, int64_t Offset,
bool IsIndexSignExt)
: Base(Base), Index(Index), Offset(Offset),
@@ -48,6 +49,13 @@ public:
SDValue getBase() const { return Base; }
SDValue getIndex() { return Index; }
SDValue getIndex() const { return Index; }
+ bool hasValidOffset() const { return Offset.hasValue(); }
+
+ // Returns true if `Other` and `*this` are both some offset from the same base
+ // pointer. In that case, `Off` is set to the offset between `*this` and
+ // `Other` (negative if `Other` is before `*this`).
+ bool equalBaseIndex(const BaseIndexOffset &Other, const SelectionDAG &DAG,
+ int64_t &Off) const;
bool equalBaseIndex(const BaseIndexOffset &Other,
const SelectionDAG &DAG) const {
@@ -55,11 +63,31 @@ public:
return equalBaseIndex(Other, DAG, Off);
}
- bool equalBaseIndex(const BaseIndexOffset &Other, const SelectionDAG &DAG,
- int64_t &Off) const;
+ // Returns true if `Other` (with size `OtherSize`) can be proven to be fully
+ // contained in `*this` (with size `Size`).
+ bool contains(const SelectionDAG &DAG, int64_t BitSize,
+ const BaseIndexOffset &Other, int64_t OtherBitSize,
+ int64_t &BitOffset) const;
+
+ bool contains(const SelectionDAG &DAG, int64_t BitSize,
+ const BaseIndexOffset &Other, int64_t OtherBitSize) const {
+ int64_t BitOffset;
+ return contains(DAG, BitSize, Other, OtherBitSize, BitOffset);
+ }
+
+ // Returns true `Op0` and `Op1` can be proven to alias/not alias, in
+ // which case `IsAlias` is set to true/false.
+ static bool computeAliasing(const SDNode *Op0,
+ const Optional<int64_t> NumBytes0,
+ const SDNode *Op1,
+ const Optional<int64_t> NumBytes1,
+ const SelectionDAG &DAG, bool &IsAlias);
+
+ /// Parses tree in N for base, index, offset addresses.
+ static BaseIndexOffset match(const SDNode *N, const SelectionDAG &DAG);
- /// Parses tree in Ptr for base, index, offset addresses.
- static BaseIndexOffset match(const LSBaseSDNode *N, const SelectionDAG &DAG);
+ void print(raw_ostream& OS) const;
+ void dump() const;
};
} // end namespace llvm
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index 6758c55c696a..147c325342fc 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/SelectionDAGISel.h - Common Base Class------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -35,6 +34,7 @@ namespace llvm {
class TargetLibraryInfo;
class FunctionLoweringInfo;
class ScheduleHazardRecognizer;
+ class SwiftErrorValueTracking;
class GCFunctionInfo;
class ScheduleDAGSDNodes;
class LoadInst;
@@ -46,6 +46,7 @@ public:
TargetMachine &TM;
const TargetLibraryInfo *LibInfo;
FunctionLoweringInfo *FuncInfo;
+ SwiftErrorValueTracking *SwiftError;
MachineFunction *MF;
MachineRegisterInfo *RegInfo;
SelectionDAG *CurDAG;
@@ -144,10 +145,12 @@ public:
OPC_CheckInteger,
OPC_CheckChild0Integer, OPC_CheckChild1Integer, OPC_CheckChild2Integer,
OPC_CheckChild3Integer, OPC_CheckChild4Integer,
- OPC_CheckCondCode,
+ OPC_CheckCondCode, OPC_CheckChild2CondCode,
OPC_CheckValueType,
OPC_CheckComplexPat,
OPC_CheckAndImm, OPC_CheckOrImm,
+ OPC_CheckImmAllOnesV,
+ OPC_CheckImmAllZerosV,
OPC_CheckFoldableChainNode,
OPC_EmitInteger,
@@ -303,7 +306,7 @@ public:
private:
// Calls to these functions are generated by tblgen.
- void Select_INLINEASM(SDNode *N);
+ void Select_INLINEASM(SDNode *N, bool Branch);
void Select_READ_REGISTER(SDNode *Op);
void Select_WRITE_REGISTER(SDNode *Op);
void Select_UNDEF(SDNode *N);
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 10f284179084..5aab9643e09d 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/SelectionDAGNodes.h - SelectionDAG Nodes ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -184,6 +183,7 @@ public:
inline unsigned getNumOperands() const;
inline const SDValue &getOperand(unsigned i) const;
inline uint64_t getConstantOperandVal(unsigned i) const;
+ inline const APInt &getConstantOperandAPInt(unsigned i) const;
inline bool isTargetMemoryOpcode() const;
inline bool isTargetOpcode() const;
inline bool isMachineOpcode() const;
@@ -232,7 +232,6 @@ template<> struct DenseMapInfo<SDValue> {
return LHS == RHS;
}
};
-template <> struct isPodLike<SDValue> { static const bool value = true; };
/// Allow casting operators to work directly on
/// SDValues as if they were SDNode*'s.
@@ -369,6 +368,13 @@ private:
bool ApproximateFuncs : 1;
bool AllowReassociation : 1;
+ // We assume instructions do not raise floating-point exceptions by default,
+ // and only those marked explicitly may do so. We could choose to represent
+ // this via a positive "FPExcept" flags like on the MI level, but having a
+ // negative "NoFPExcept" flag here (that defaults to true) makes the flag
+ // intersection logic more straightforward.
+ bool NoFPExcept : 1;
+
public:
/// Default constructor turns off all optimization flags.
SDNodeFlags()
@@ -376,7 +382,7 @@ public:
Exact(false), NoNaNs(false), NoInfs(false),
NoSignedZeros(false), AllowReciprocal(false), VectorReduction(false),
AllowContract(false), ApproximateFuncs(false),
- AllowReassociation(false) {}
+ AllowReassociation(false), NoFPExcept(true) {}
/// Propagate the fast-math-flags from an IR FPMathOperator.
void copyFMF(const FPMathOperator &FPMO) {
@@ -439,6 +445,10 @@ public:
setDefined();
AllowReassociation = b;
}
+ void setFPExcept(bool b) {
+ setDefined();
+ NoFPExcept = !b;
+ }
// These are accessors for each flag.
bool hasNoUnsignedWrap() const { return NoUnsignedWrap; }
@@ -452,9 +462,10 @@ public:
bool hasAllowContract() const { return AllowContract; }
bool hasApproximateFuncs() const { return ApproximateFuncs; }
bool hasAllowReassociation() const { return AllowReassociation; }
+ bool hasFPExcept() const { return !NoFPExcept; }
bool isFast() const {
- return NoSignedZeros && AllowReciprocal && NoNaNs && NoInfs &&
+ return NoSignedZeros && AllowReciprocal && NoNaNs && NoInfs && NoFPExcept &&
AllowContract && ApproximateFuncs && AllowReassociation;
}
@@ -474,6 +485,7 @@ public:
AllowContract &= Flags.AllowContract;
ApproximateFuncs &= Flags.ApproximateFuncs;
AllowReassociation &= Flags.AllowReassociation;
+ NoFPExcept &= Flags.NoFPExcept;
}
};
@@ -489,6 +501,17 @@ protected:
// SubclassData. These are designed to fit within a uint16_t so they pack
// with NodeType.
+#if defined(_AIX) && (!defined(__GNUC__) || defined(__ibmxl__))
+// Except for GCC; by default, AIX compilers store bit-fields in 4-byte words
+// and give the `pack` pragma push semantics.
+#define BEGIN_TWO_BYTE_PACK() _Pragma("pack(2)")
+#define END_TWO_BYTE_PACK() _Pragma("pack(pop)")
+#else
+#define BEGIN_TWO_BYTE_PACK()
+#define END_TWO_BYTE_PACK()
+#endif
+
+BEGIN_TWO_BYTE_PACK()
class SDNodeBitfields {
friend class SDNode;
friend class MemIntrinsicSDNode;
@@ -561,6 +584,9 @@ protected:
LoadSDNodeBitfields LoadSDNodeBits;
StoreSDNodeBitfields StoreSDNodeBits;
};
+END_TWO_BYTE_PACK()
+#undef BEGIN_TWO_BYTE_PACK
+#undef END_TWO_BYTE_PACK
// RawSDNodeBits must cover the entirety of the union. This means that all of
// the union's members must have size <= RawSDNodeBits. We write the RHS as
@@ -678,6 +704,8 @@ public:
case ISD::STRICT_FFLOOR:
case ISD::STRICT_FROUND:
case ISD::STRICT_FTRUNC:
+ case ISD::STRICT_FP_ROUND:
+ case ISD::STRICT_FP_EXTEND:
return true;
}
}
@@ -898,9 +926,17 @@ public:
/// Return the number of values used by this operation.
unsigned getNumOperands() const { return NumOperands; }
+ /// Return the maximum number of operands that a SDNode can hold.
+ static constexpr size_t getMaxNumOperands() {
+ return std::numeric_limits<decltype(SDNode::NumOperands)>::max();
+ }
+
/// Helper method returns the integer value of a ConstantSDNode operand.
inline uint64_t getConstantOperandVal(unsigned Num) const;
+ /// Helper method returns the APInt of a ConstantSDNode operand.
+ inline const APInt &getConstantOperandAPInt(unsigned Num) const;
+
const SDValue &getOperand(unsigned Num) const {
assert(Num < NumOperands && "Invalid child # of SDNode!");
return OperandList[Num];
@@ -1128,6 +1164,10 @@ inline uint64_t SDValue::getConstantOperandVal(unsigned i) const {
return Node->getConstantOperandVal(i);
}
+inline const APInt &SDValue::getConstantOperandAPInt(unsigned i) const {
+ return Node->getConstantOperandAPInt(i);
+}
+
inline bool SDValue::isTargetOpcode() const {
return Node->isTargetOpcode();
}
@@ -1356,6 +1396,8 @@ public:
N->getOpcode() == ISD::ATOMIC_LOAD_MAX ||
N->getOpcode() == ISD::ATOMIC_LOAD_UMIN ||
N->getOpcode() == ISD::ATOMIC_LOAD_UMAX ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_FADD ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_FSUB ||
N->getOpcode() == ISD::ATOMIC_LOAD ||
N->getOpcode() == ISD::ATOMIC_STORE ||
N->getOpcode() == ISD::MLOAD ||
@@ -1372,7 +1414,10 @@ class AtomicSDNode : public MemSDNode {
public:
AtomicSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTL,
EVT MemVT, MachineMemOperand *MMO)
- : MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {}
+ : MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
+ assert(((Opc != ISD::ATOMIC_LOAD && Opc != ISD::ATOMIC_STORE) ||
+ MMO->isAtomic()) && "then why are we using an AtomicSDNode?");
+ }
const SDValue &getBasePtr() const { return getOperand(1); }
const SDValue &getVal() const { return getOperand(2); }
@@ -1408,6 +1453,8 @@ public:
N->getOpcode() == ISD::ATOMIC_LOAD_MAX ||
N->getOpcode() == ISD::ATOMIC_LOAD_UMIN ||
N->getOpcode() == ISD::ATOMIC_LOAD_UMAX ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_FADD ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_FSUB ||
N->getOpcode() == ISD::ATOMIC_LOAD ||
N->getOpcode() == ISD::ATOMIC_STORE;
}
@@ -1467,14 +1514,16 @@ public:
bool isSplat() const { return isSplatMask(Mask, getValueType(0)); }
- int getSplatIndex() const {
+ int getSplatIndex() const {
assert(isSplat() && "Cannot get splat index for non-splat!");
EVT VT = getValueType(0);
- for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i) {
+ for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i)
if (Mask[i] >= 0)
return Mask[i];
- }
- llvm_unreachable("Splat with all undef indices?");
+
+ // We can choose any index value here and be correct because all elements
+ // are undefined. Return 0 for better potential for callers to simplify.
+ return 0;
}
static bool isSplatMask(const int *Mask, EVT VT);
@@ -1536,6 +1585,10 @@ uint64_t SDNode::getConstantOperandVal(unsigned Num) const {
return cast<ConstantSDNode>(getOperand(Num))->getZExtValue();
}
+const APInt &SDNode::getConstantOperandAPInt(unsigned Num) const {
+ return cast<ConstantSDNode>(getOperand(Num))->getAPIntValue();
+}
+
class ConstantFPSDNode : public SDNode {
friend class SelectionDAG;
@@ -1603,20 +1656,36 @@ SDValue peekThroughBitcasts(SDValue V);
/// If \p V is not a bitcasted one-use value, it is returned as-is.
SDValue peekThroughOneUseBitcasts(SDValue V);
+/// Return the non-extracted vector source operand of \p V if it exists.
+/// If \p V is not an extracted subvector, it is returned as-is.
+SDValue peekThroughExtractSubvectors(SDValue V);
+
/// Returns true if \p V is a bitwise not operation. Assumes that an all ones
/// constant is canonicalized to be operand 1.
-bool isBitwiseNot(SDValue V);
+bool isBitwiseNot(SDValue V, bool AllowUndefs = false);
/// Returns the SDNode if it is a constant splat BuildVector or constant int.
-ConstantSDNode *isConstOrConstSplat(SDValue N, bool AllowUndefs = false);
+ConstantSDNode *isConstOrConstSplat(SDValue N, bool AllowUndefs = false,
+ bool AllowTruncation = false);
+
+/// Returns the SDNode if it is a demanded constant splat BuildVector or
+/// constant int.
+ConstantSDNode *isConstOrConstSplat(SDValue N, const APInt &DemandedElts,
+ bool AllowUndefs = false,
+ bool AllowTruncation = false);
/// Returns the SDNode if it is a constant splat BuildVector or constant float.
ConstantFPSDNode *isConstOrConstSplatFP(SDValue N, bool AllowUndefs = false);
+/// Returns the SDNode if it is a demanded constant splat BuildVector or
+/// constant float.
+ConstantFPSDNode *isConstOrConstSplatFP(SDValue N, const APInt &DemandedElts,
+ bool AllowUndefs = false);
+
/// Return true if the value is a constant 0 integer or a splatted vector of
-/// a constant 0 integer (with no undefs).
+/// a constant 0 integer (with no undefs by default).
/// Build vector implicit truncation is not an issue for null values.
-bool isNullOrNullSplat(SDValue V);
+bool isNullOrNullSplat(SDValue V, bool AllowUndefs = false);
/// Return true if the value is a constant 1 integer or a splatted vector of a
/// constant 1 integer (with no undefs).
@@ -1673,6 +1742,38 @@ public:
}
};
+/// This SDNode is used for LIFETIME_START/LIFETIME_END values, which indicate
+/// the offet and size that are started/ended in the underlying FrameIndex.
+class LifetimeSDNode : public SDNode {
+ friend class SelectionDAG;
+ int64_t Size;
+ int64_t Offset; // -1 if offset is unknown.
+
+ LifetimeSDNode(unsigned Opcode, unsigned Order, const DebugLoc &dl,
+ SDVTList VTs, int64_t Size, int64_t Offset)
+ : SDNode(Opcode, Order, dl, VTs), Size(Size), Offset(Offset) {}
+public:
+ int64_t getFrameIndex() const {
+ return cast<FrameIndexSDNode>(getOperand(1))->getIndex();
+ }
+
+ bool hasOffset() const { return Offset >= 0; }
+ int64_t getOffset() const {
+ assert(hasOffset() && "offset is unknown");
+ return Offset;
+ }
+ int64_t getSize() const {
+ assert(hasOffset() && "offset is unknown");
+ return Size;
+ }
+
+ // Methods to support isa and dyn_cast
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::LIFETIME_START ||
+ N->getOpcode() == ISD::LIFETIME_END;
+ }
+};
+
class JumpTableSDNode : public SDNode {
friend class SelectionDAG;
@@ -1818,12 +1919,31 @@ public:
unsigned MinSplatBits = 0,
bool isBigEndian = false) const;
+ /// Returns the demanded splatted value or a null value if this is not a
+ /// splat.
+ ///
+ /// The DemandedElts mask indicates the elements that must be in the splat.
+ /// If passed a non-null UndefElements bitvector, it will resize it to match
+ /// the vector width and set the bits where elements are undef.
+ SDValue getSplatValue(const APInt &DemandedElts,
+ BitVector *UndefElements = nullptr) const;
+
/// Returns the splatted value or a null value if this is not a splat.
///
/// If passed a non-null UndefElements bitvector, it will resize it to match
/// the vector width and set the bits where elements are undef.
SDValue getSplatValue(BitVector *UndefElements = nullptr) const;
+ /// Returns the demanded splatted constant or null if this is not a constant
+ /// splat.
+ ///
+ /// The DemandedElts mask indicates the elements that must be in the splat.
+ /// If passed a non-null UndefElements bitvector, it will resize it to match
+ /// the vector width and set the bits where elements are undef.
+ ConstantSDNode *
+ getConstantSplatNode(const APInt &DemandedElts,
+ BitVector *UndefElements = nullptr) const;
+
/// Returns the splatted constant or null if this is not a constant
/// splat.
///
@@ -1832,6 +1952,16 @@ public:
ConstantSDNode *
getConstantSplatNode(BitVector *UndefElements = nullptr) const;
+ /// Returns the demanded splatted constant FP or null if this is not a
+ /// constant FP splat.
+ ///
+ /// The DemandedElts mask indicates the elements that must be in the splat.
+ /// If passed a non-null UndefElements bitvector, it will resize it to match
+ /// the vector width and set the bits where elements are undef.
+ ConstantFPSDNode *
+ getConstantFPSplatNode(const APInt &DemandedElts,
+ BitVector *UndefElements = nullptr) const;
+
/// Returns the splatted constant FP or null if this is not a constant
/// FP splat.
///
@@ -1956,8 +2086,10 @@ class LabelSDNode : public SDNode {
MCSymbol *Label;
- LabelSDNode(unsigned Order, const DebugLoc &dl, MCSymbol *L)
- : SDNode(ISD::EH_LABEL, Order, dl, getSDVTList(MVT::Other)), Label(L) {}
+ LabelSDNode(unsigned Opcode, unsigned Order, const DebugLoc &dl, MCSymbol *L)
+ : SDNode(Opcode, Order, dl, getSDVTList(MVT::Other)), Label(L) {
+ assert(LabelSDNode::classof(this) && "not a label opcode");
+ }
public:
MCSymbol *getLabel() const { return Label; }
@@ -2049,6 +2181,8 @@ public:
: MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
LSBaseSDNodeBits.AddressingMode = AM;
assert(getAddressingMode() == AM && "Value truncated");
+ assert((!MMO->isAtomic() || MMO->isVolatile()) &&
+ "use an AtomicSDNode instead for non-volatile atomics");
}
const SDValue &getOffset() const {
@@ -2473,18 +2607,6 @@ namespace ISD {
cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
}
- /// Return true if the node is a math/logic binary operator. This corresponds
- /// to the IR function of the same name.
- inline bool isBinaryOp(const SDNode *N) {
- auto Op = N->getOpcode();
- return (Op == ISD::ADD || Op == ISD::SUB || Op == ISD::MUL ||
- Op == ISD::AND || Op == ISD::OR || Op == ISD::XOR ||
- Op == ISD::SHL || Op == ISD::SRL || Op == ISD::SRA ||
- Op == ISD::SDIV || Op == ISD::UDIV || Op == ISD::SREM ||
- Op == ISD::UREM || Op == ISD::FADD || Op == ISD::FSUB ||
- Op == ISD::FMUL || Op == ISD::FDIV || Op == ISD::FREM);
- }
-
/// Attempt to match a unary predicate against a scalar/splat constant or
/// every element of a constant BUILD_VECTOR.
/// If AllowUndef is true, then UNDEF elements will pass nullptr to Match.
@@ -2495,10 +2617,11 @@ namespace ISD {
/// Attempt to match a binary predicate against a pair of scalar/splat
/// constants or every element of a pair of constant BUILD_VECTORs.
/// If AllowUndef is true, then UNDEF elements will pass nullptr to Match.
+ /// If AllowTypeMismatch is true then RetType + ArgTypes don't need to match.
bool matchBinaryPredicate(
SDValue LHS, SDValue RHS,
std::function<bool(ConstantSDNode *, ConstantSDNode *)> Match,
- bool AllowUndefs = false);
+ bool AllowUndefs = false, bool AllowTypeMismatch = false);
} // end namespace ISD
} // end namespace llvm
diff --git a/include/llvm/CodeGen/SelectionDAGTargetInfo.h b/include/llvm/CodeGen/SelectionDAGTargetInfo.h
index 45c1df48a5e6..6f6a9a5ae269 100644
--- a/include/llvm/CodeGen/SelectionDAGTargetInfo.h
+++ b/include/llvm/CodeGen/SelectionDAGTargetInfo.h
@@ -1,9 +1,8 @@
//==- llvm/CodeGen/SelectionDAGTargetInfo.h - SelectionDAG Info --*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -148,6 +147,14 @@ public:
return std::make_pair(SDValue(), SDValue());
}
+ virtual SDValue EmitTargetCodeForSetTag(SelectionDAG &DAG, const SDLoc &dl,
+ SDValue Chain, SDValue Addr,
+ SDValue Size,
+ MachinePointerInfo DstPtrInfo,
+ bool ZeroData) const {
+ return SDValue();
+ }
+
// Return true when the decision to generate FMA's (or FMS, FMLA etc) rather
// than FMUL and ADD is delegated to the machine combiner.
virtual bool generateFMAsInMachineCombiner(CodeGenOpt::Level OptLevel) const {
diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h
index 8c8a7be459fd..2b32a4d30dff 100644
--- a/include/llvm/CodeGen/SlotIndexes.h
+++ b/include/llvm/CodeGen/SlotIndexes.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/SlotIndexes.h - Slot indexes representation -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -302,8 +301,6 @@ class raw_ostream;
}
};
- template <> struct isPodLike<SlotIndex> { static const bool value = true; };
-
inline raw_ostream& operator<<(raw_ostream &os, SlotIndex li) {
li.print(os);
return os;
@@ -311,20 +308,6 @@ class raw_ostream;
using IdxMBBPair = std::pair<SlotIndex, MachineBasicBlock *>;
- inline bool operator<(SlotIndex V, const IdxMBBPair &IM) {
- return V < IM.first;
- }
-
- inline bool operator<(const IdxMBBPair &IM, SlotIndex V) {
- return IM.first < V;
- }
-
- struct Idx2MBBCompare {
- bool operator()(const IdxMBBPair &LHS, const IdxMBBPair &RHS) const {
- return LHS.first < RHS.first;
- }
- };
-
/// SlotIndexes pass.
///
/// This pass assigns indexes to each instruction.
@@ -336,10 +319,6 @@ class raw_ostream;
using IndexList = ilist<IndexListEntry>;
IndexList indexList;
-#ifdef EXPENSIVE_CHECKS
- IndexList graveyardList;
-#endif // EXPENSIVE_CHECKS
-
MachineFunction *mf;
using Mi2IndexMap = DenseMap<const MachineInstr *, SlotIndex>;
@@ -368,7 +347,7 @@ class raw_ostream;
public:
static char ID;
- SlotIndexes() : MachineFunctionPass(ID) {
+ SlotIndexes() : MachineFunctionPass(ID), mf(nullptr) {
initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
}
@@ -385,9 +364,6 @@ class raw_ostream;
/// Dump the indexes.
void dump() const;
- /// Renumber the index list, providing space for new instructions.
- void renumberIndexes();
-
/// Repair indexes after adding and removing instructions.
void repairIndexesInRange(MachineBasicBlock *MBB,
MachineBasicBlock::iterator Begin,
@@ -516,7 +492,9 @@ class raw_ostream;
/// Move iterator to the next IdxMBBPair where the SlotIndex is greater or
/// equal to \p To.
MBBIndexIterator advanceMBBIndex(MBBIndexIterator I, SlotIndex To) const {
- return std::lower_bound(I, idx2MBBMap.end(), To);
+ return std::partition_point(
+ I, idx2MBBMap.end(),
+ [=](const IdxMBBPair &IM) { return IM.first < To; });
}
/// Get an iterator pointing to the IdxMBBPair with the biggest SlotIndex
@@ -552,29 +530,6 @@ class raw_ostream;
return J->second;
}
- /// Returns the MBB covering the given range, or null if the range covers
- /// more than one basic block.
- MachineBasicBlock* getMBBCoveringRange(SlotIndex start, SlotIndex end) const {
-
- assert(start < end && "Backwards ranges not allowed.");
- MBBIndexIterator itr = findMBBIndex(start);
- if (itr == MBBIndexEnd()) {
- itr = std::prev(itr);
- return itr->second;
- }
-
- // Check that we don't cross the boundary into this block.
- if (itr->first < end)
- return nullptr;
-
- itr = std::prev(itr);
-
- if (itr->first <= start)
- return itr->second;
-
- return nullptr;
- }
-
/// Insert the given machine instruction into the mapping. Returns the
/// assigned index.
/// If Late is set and there are null indexes between mi's neighboring
@@ -680,33 +635,7 @@ class raw_ostream;
idx2MBBMap.push_back(IdxMBBPair(startIdx, mbb));
renumberIndexes(newItr);
- llvm::sort(idx2MBBMap, Idx2MBBCompare());
- }
-
- /// Free the resources that were required to maintain a SlotIndex.
- ///
- /// Once an index is no longer needed (for instance because the instruction
- /// at that index has been moved), the resources required to maintain the
- /// index can be relinquished to reduce memory use and improve renumbering
- /// performance. Any remaining SlotIndex objects that point to the same
- /// index are left 'dangling' (much the same as a dangling pointer to a
- /// freed object) and should not be accessed, except to destruct them.
- ///
- /// Like dangling pointers, access to dangling SlotIndexes can cause
- /// painful-to-track-down bugs, especially if the memory for the index
- /// previously pointed to has been re-used. To detect dangling SlotIndex
- /// bugs, build with EXPENSIVE_CHECKS=1. This will cause "erased" indexes to
- /// be retained in a graveyard instead of being freed. Operations on indexes
- /// in the graveyard will trigger an assertion.
- void eraseIndex(SlotIndex index) {
- IndexListEntry *entry = index.listEntry();
-#ifdef EXPENSIVE_CHECKS
- indexList.remove(entry);
- graveyardList.push_back(entry);
- entry->setPoison();
-#else
- indexList.erase(entry);
-#endif
+ llvm::sort(idx2MBBMap, less_first());
}
};
diff --git a/include/llvm/CodeGen/StackMaps.h b/include/llvm/CodeGen/StackMaps.h
index 8be9ae378557..d7d88de6f682 100644
--- a/include/llvm/CodeGen/StackMaps.h
+++ b/include/llvm/CodeGen/StackMaps.h
@@ -1,9 +1,8 @@
//===- StackMaps.h - StackMaps ----------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/StackProtector.h b/include/llvm/CodeGen/StackProtector.h
index a506ac636a17..2bdf4425e24a 100644
--- a/include/llvm/CodeGen/StackProtector.h
+++ b/include/llvm/CodeGen/StackProtector.h
@@ -1,9 +1,8 @@
//===- StackProtector.h - Stack Protector Insertion -------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -62,12 +61,6 @@ private:
/// protection when -fstack-protection is used.
unsigned SSPBufferSize = 0;
- /// VisitedPHIs - The set of PHI nodes visited when determining
- /// if a variable's reference has been taken. This set
- /// is maintained to ensure we don't visit the same PHI node multiple
- /// times.
- SmallPtrSet<const PHINode *, 16> VisitedPHIs;
-
// A prologue is generated.
bool HasPrologue = false;
diff --git a/include/llvm/CodeGen/SwiftErrorValueTracking.h b/include/llvm/CodeGen/SwiftErrorValueTracking.h
new file mode 100644
index 000000000000..fb7a12853c09
--- /dev/null
+++ b/include/llvm/CodeGen/SwiftErrorValueTracking.h
@@ -0,0 +1,110 @@
+//===- SwiftErrorValueTracking.h - Track swifterror VReg vals --*- C++ -*--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This implements a limited mem2reg-like analysis to promote uses of function
+// arguments and allocas marked with swiftalloc from memory into virtual
+// registers tracked by this class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFTERRORVALUETRACKING_H
+#define SWIFTERRORVALUETRACKING_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Register.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/DebugLoc.h"
+#include <functional>
+#include <type_traits>
+#include <utility>
+
+
+namespace llvm {
+ class Function;
+ class MachineBasicBlock;
+ class MachineFunction;
+ class MachineInstr;
+ class TargetInstrInfo;
+ class TargetLowering;
+
+class SwiftErrorValueTracking {
+ // Some useful objects to reduce the number of function arguments needed.
+ MachineFunction *MF;
+ const Function *Fn;
+ const TargetLowering *TLI;
+ const TargetInstrInfo *TII;
+
+ /// A map from swifterror value in a basic block to the virtual register it is
+ /// currently represented by.
+ DenseMap<std::pair<const MachineBasicBlock *, const Value *>, Register>
+ VRegDefMap;
+
+ /// A list of upward exposed vreg uses that need to be satisfied by either a
+ /// copy def or a phi node at the beginning of the basic block representing
+ /// the predecessor(s) swifterror value.
+ DenseMap<std::pair<const MachineBasicBlock *, const Value *>, Register>
+ VRegUpwardsUse;
+
+ /// A map from instructions that define/use a swifterror value to the virtual
+ /// register that represents that def/use.
+ llvm::DenseMap<PointerIntPair<const Instruction *, 1, bool>, Register>
+ VRegDefUses;
+
+ /// The swifterror argument of the current function.
+ const Value *SwiftErrorArg;
+
+ using SwiftErrorValues = SmallVector<const Value*, 1>;
+ /// A function can only have a single swifterror argument. And if it does
+ /// have a swifterror argument, it must be the first entry in
+ /// SwiftErrorVals.
+ SwiftErrorValues SwiftErrorVals;
+
+public:
+ /// Initialize data structures for specified new function.
+ void setFunction(MachineFunction &MF);
+
+ /// Get the (unique) function argument that was marked swifterror, or nullptr
+ /// if this function has no swifterror args.
+ const Value *getFunctionArg() const {
+ return SwiftErrorArg;
+ }
+
+ /// Get or create the swifterror value virtual register in
+ /// VRegDefMap for this basic block.
+ Register getOrCreateVReg(const MachineBasicBlock *, const Value *);
+
+ /// Set the swifterror virtual register in the VRegDefMap for this
+ /// basic block.
+ void setCurrentVReg(const MachineBasicBlock *MBB, const Value *, Register);
+
+ /// Get or create the swifterror value virtual register for a def of a
+ /// swifterror by an instruction.
+ Register getOrCreateVRegDefAt(const Instruction *, const MachineBasicBlock *,
+ const Value *);
+
+ /// Get or create the swifterror value virtual register for a use of a
+ /// swifterror by an instruction.
+ Register getOrCreateVRegUseAt(const Instruction *, const MachineBasicBlock *,
+ const Value *);
+
+ /// Create initial definitions of swifterror values in the entry block of the
+ /// current function.
+ bool createEntriesInEntryBlock(DebugLoc DbgLoc);
+
+ /// Propagate assigned swifterror vregs through a function, synthesizing PHI
+ /// nodes when needed to maintain consistency.
+ void propagateVRegs();
+
+ void preassignVRegs(MachineBasicBlock *MBB, BasicBlock::const_iterator Begin,
+ BasicBlock::const_iterator End);
+};
+
+}
+
+#endif
diff --git a/include/llvm/CodeGen/SwitchLoweringUtils.h b/include/llvm/CodeGen/SwitchLoweringUtils.h
new file mode 100644
index 000000000000..62134dc792f7
--- /dev/null
+++ b/include/llvm/CodeGen/SwitchLoweringUtils.h
@@ -0,0 +1,297 @@
+//===- SwitchLoweringUtils.h - Switch Lowering ------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SWITCHLOWERINGUTILS_H
+#define LLVM_CODEGEN_SWITCHLOWERINGUTILS_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/Support/BranchProbability.h"
+
+namespace llvm {
+
+class FunctionLoweringInfo;
+class MachineBasicBlock;
+
+namespace SwitchCG {
+
+enum CaseClusterKind {
+ /// A cluster of adjacent case labels with the same destination, or just one
+ /// case.
+ CC_Range,
+ /// A cluster of cases suitable for jump table lowering.
+ CC_JumpTable,
+ /// A cluster of cases suitable for bit test lowering.
+ CC_BitTests
+};
+
+/// A cluster of case labels.
+struct CaseCluster {
+ CaseClusterKind Kind;
+ const ConstantInt *Low, *High;
+ union {
+ MachineBasicBlock *MBB;
+ unsigned JTCasesIndex;
+ unsigned BTCasesIndex;
+ };
+ BranchProbability Prob;
+
+ static CaseCluster range(const ConstantInt *Low, const ConstantInt *High,
+ MachineBasicBlock *MBB, BranchProbability Prob) {
+ CaseCluster C;
+ C.Kind = CC_Range;
+ C.Low = Low;
+ C.High = High;
+ C.MBB = MBB;
+ C.Prob = Prob;
+ return C;
+ }
+
+ static CaseCluster jumpTable(const ConstantInt *Low, const ConstantInt *High,
+ unsigned JTCasesIndex, BranchProbability Prob) {
+ CaseCluster C;
+ C.Kind = CC_JumpTable;
+ C.Low = Low;
+ C.High = High;
+ C.JTCasesIndex = JTCasesIndex;
+ C.Prob = Prob;
+ return C;
+ }
+
+ static CaseCluster bitTests(const ConstantInt *Low, const ConstantInt *High,
+ unsigned BTCasesIndex, BranchProbability Prob) {
+ CaseCluster C;
+ C.Kind = CC_BitTests;
+ C.Low = Low;
+ C.High = High;
+ C.BTCasesIndex = BTCasesIndex;
+ C.Prob = Prob;
+ return C;
+ }
+};
+
+using CaseClusterVector = std::vector<CaseCluster>;
+using CaseClusterIt = CaseClusterVector::iterator;
+
+/// Sort Clusters and merge adjacent cases.
+void sortAndRangeify(CaseClusterVector &Clusters);
+
+struct CaseBits {
+ uint64_t Mask = 0;
+ MachineBasicBlock *BB = nullptr;
+ unsigned Bits = 0;
+ BranchProbability ExtraProb;
+
+ CaseBits() = default;
+ CaseBits(uint64_t mask, MachineBasicBlock *bb, unsigned bits,
+ BranchProbability Prob)
+ : Mask(mask), BB(bb), Bits(bits), ExtraProb(Prob) {}
+};
+
+using CaseBitsVector = std::vector<CaseBits>;
+
+/// This structure is used to communicate between SelectionDAGBuilder and
+/// SDISel for the code generation of additional basic blocks needed by
+/// multi-case switch statements.
+struct CaseBlock {
+ // For the GISel interface.
+ struct PredInfoPair {
+ CmpInst::Predicate Pred;
+ // Set when no comparison should be emitted.
+ bool NoCmp;
+ };
+ union {
+ // The condition code to use for the case block's setcc node.
+ // Besides the integer condition codes, this can also be SETTRUE, in which
+ // case no comparison gets emitted.
+ ISD::CondCode CC;
+ struct PredInfoPair PredInfo;
+ };
+
+ // The LHS/MHS/RHS of the comparison to emit.
+ // Emit by default LHS op RHS. MHS is used for range comparisons:
+ // If MHS is not null: (LHS <= MHS) and (MHS <= RHS).
+ const Value *CmpLHS, *CmpMHS, *CmpRHS;
+
+ // The block to branch to if the setcc is true/false.
+ MachineBasicBlock *TrueBB, *FalseBB;
+
+ // The block into which to emit the code for the setcc and branches.
+ MachineBasicBlock *ThisBB;
+
+ /// The debug location of the instruction this CaseBlock was
+ /// produced from.
+ SDLoc DL;
+ DebugLoc DbgLoc;
+
+ // Branch weights.
+ BranchProbability TrueProb, FalseProb;
+
+ // Constructor for SelectionDAG.
+ CaseBlock(ISD::CondCode cc, const Value *cmplhs, const Value *cmprhs,
+ const Value *cmpmiddle, MachineBasicBlock *truebb,
+ MachineBasicBlock *falsebb, MachineBasicBlock *me, SDLoc dl,
+ BranchProbability trueprob = BranchProbability::getUnknown(),
+ BranchProbability falseprob = BranchProbability::getUnknown())
+ : CC(cc), CmpLHS(cmplhs), CmpMHS(cmpmiddle), CmpRHS(cmprhs),
+ TrueBB(truebb), FalseBB(falsebb), ThisBB(me), DL(dl),
+ TrueProb(trueprob), FalseProb(falseprob) {}
+
+ // Constructor for GISel.
+ CaseBlock(CmpInst::Predicate pred, bool nocmp, const Value *cmplhs,
+ const Value *cmprhs, const Value *cmpmiddle,
+ MachineBasicBlock *truebb, MachineBasicBlock *falsebb,
+ MachineBasicBlock *me, DebugLoc dl,
+ BranchProbability trueprob = BranchProbability::getUnknown(),
+ BranchProbability falseprob = BranchProbability::getUnknown())
+ : PredInfo({pred, nocmp}), CmpLHS(cmplhs), CmpMHS(cmpmiddle),
+ CmpRHS(cmprhs), TrueBB(truebb), FalseBB(falsebb), ThisBB(me),
+ DbgLoc(dl), TrueProb(trueprob), FalseProb(falseprob) {}
+};
+
+struct JumpTable {
+ /// The virtual register containing the index of the jump table entry
+ /// to jump to.
+ unsigned Reg;
+ /// The JumpTableIndex for this jump table in the function.
+ unsigned JTI;
+ /// The MBB into which to emit the code for the indirect jump.
+ MachineBasicBlock *MBB;
+ /// The MBB of the default bb, which is a successor of the range
+ /// check MBB. This is when updating PHI nodes in successors.
+ MachineBasicBlock *Default;
+
+ JumpTable(unsigned R, unsigned J, MachineBasicBlock *M, MachineBasicBlock *D)
+ : Reg(R), JTI(J), MBB(M), Default(D) {}
+};
+struct JumpTableHeader {
+ APInt First;
+ APInt Last;
+ const Value *SValue;
+ MachineBasicBlock *HeaderBB;
+ bool Emitted;
+ bool OmitRangeCheck;
+
+ JumpTableHeader(APInt F, APInt L, const Value *SV, MachineBasicBlock *H,
+ bool E = false)
+ : First(std::move(F)), Last(std::move(L)), SValue(SV), HeaderBB(H),
+ Emitted(E), OmitRangeCheck(false) {}
+};
+using JumpTableBlock = std::pair<JumpTableHeader, JumpTable>;
+
+struct BitTestCase {
+ uint64_t Mask;
+ MachineBasicBlock *ThisBB;
+ MachineBasicBlock *TargetBB;
+ BranchProbability ExtraProb;
+
+ BitTestCase(uint64_t M, MachineBasicBlock *T, MachineBasicBlock *Tr,
+ BranchProbability Prob)
+ : Mask(M), ThisBB(T), TargetBB(Tr), ExtraProb(Prob) {}
+};
+
+using BitTestInfo = SmallVector<BitTestCase, 3>;
+
+struct BitTestBlock {
+ APInt First;
+ APInt Range;
+ const Value *SValue;
+ unsigned Reg;
+ MVT RegVT;
+ bool Emitted;
+ bool ContiguousRange;
+ MachineBasicBlock *Parent;
+ MachineBasicBlock *Default;
+ BitTestInfo Cases;
+ BranchProbability Prob;
+ BranchProbability DefaultProb;
+
+ BitTestBlock(APInt F, APInt R, const Value *SV, unsigned Rg, MVT RgVT, bool E,
+ bool CR, MachineBasicBlock *P, MachineBasicBlock *D,
+ BitTestInfo C, BranchProbability Pr)
+ : First(std::move(F)), Range(std::move(R)), SValue(SV), Reg(Rg),
+ RegVT(RgVT), Emitted(E), ContiguousRange(CR), Parent(P), Default(D),
+ Cases(std::move(C)), Prob(Pr) {}
+};
+
+/// Return the range of value within a range.
+uint64_t getJumpTableRange(const CaseClusterVector &Clusters, unsigned First,
+ unsigned Last);
+
+/// Return the number of cases within a range.
+uint64_t getJumpTableNumCases(const SmallVectorImpl<unsigned> &TotalCases,
+ unsigned First, unsigned Last);
+
+struct SwitchWorkListItem {
+ MachineBasicBlock *MBB;
+ CaseClusterIt FirstCluster;
+ CaseClusterIt LastCluster;
+ const ConstantInt *GE;
+ const ConstantInt *LT;
+ BranchProbability DefaultProb;
+};
+using SwitchWorkList = SmallVector<SwitchWorkListItem, 4>;
+
+class SwitchLowering {
+public:
+ SwitchLowering(FunctionLoweringInfo &funcinfo) : FuncInfo(funcinfo) {}
+
+ void init(const TargetLowering &tli, const TargetMachine &tm,
+ const DataLayout &dl) {
+ TLI = &tli;
+ TM = &tm;
+ DL = &dl;
+ }
+
+ /// Vector of CaseBlock structures used to communicate SwitchInst code
+ /// generation information.
+ std::vector<CaseBlock> SwitchCases;
+
+ /// Vector of JumpTable structures used to communicate SwitchInst code
+ /// generation information.
+ std::vector<JumpTableBlock> JTCases;
+
+ /// Vector of BitTestBlock structures used to communicate SwitchInst code
+ /// generation information.
+ std::vector<BitTestBlock> BitTestCases;
+
+ void findJumpTables(CaseClusterVector &Clusters, const SwitchInst *SI,
+ MachineBasicBlock *DefaultMBB);
+
+ bool buildJumpTable(const CaseClusterVector &Clusters, unsigned First,
+ unsigned Last, const SwitchInst *SI,
+ MachineBasicBlock *DefaultMBB, CaseCluster &JTCluster);
+
+
+ void findBitTestClusters(CaseClusterVector &Clusters, const SwitchInst *SI);
+
+ /// Build a bit test cluster from Clusters[First..Last]. Returns false if it
+ /// decides it's not a good idea.
+ bool buildBitTests(CaseClusterVector &Clusters, unsigned First, unsigned Last,
+ const SwitchInst *SI, CaseCluster &BTCluster);
+
+ virtual void addSuccessorWithProb(
+ MachineBasicBlock *Src, MachineBasicBlock *Dst,
+ BranchProbability Prob = BranchProbability::getUnknown()) = 0;
+
+ virtual ~SwitchLowering() = default;
+
+private:
+ const TargetLowering *TLI;
+ const TargetMachine *TM;
+ const DataLayout *DL;
+ FunctionLoweringInfo &FuncInfo;
+};
+
+} // namespace SwitchCG
+} // namespace llvm
+
+#endif // LLVM_CODEGEN_SWITCHLOWERINGUTILS_H
+
diff --git a/include/llvm/CodeGen/TailDuplicator.h b/include/llvm/CodeGen/TailDuplicator.h
index be6562c85f2e..358798d5ed60 100644
--- a/include/llvm/CodeGen/TailDuplicator.h
+++ b/include/llvm/CodeGen/TailDuplicator.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/TailDuplicator.h ----------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/TargetCallingConv.h b/include/llvm/CodeGen/TargetCallingConv.h
index 7d138f585171..aebeeecbe506 100644
--- a/include/llvm/CodeGen/TargetCallingConv.h
+++ b/include/llvm/CodeGen/TargetCallingConv.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/TargetCallingConv.h - Calling Convention ---*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -46,9 +45,12 @@ namespace ISD {
unsigned IsInConsecutiveRegsLast : 1;
unsigned IsInConsecutiveRegs : 1;
unsigned IsCopyElisionCandidate : 1; ///< Argument copy elision candidate
+ unsigned IsPointer : 1;
unsigned ByValSize; ///< Byval struct size
+ unsigned PointerAddrSpace; ///< Address space of pointer argument
+
public:
ArgFlagsTy()
: IsZExt(0), IsSExt(0), IsInReg(0), IsSRet(0), IsByVal(0), IsNest(0),
@@ -56,8 +58,9 @@ namespace ISD {
IsSwiftSelf(0), IsSwiftError(0), IsHva(0), IsHvaStart(0),
IsSecArgPass(0), ByValAlign(0), OrigAlign(0),
IsInConsecutiveRegsLast(0), IsInConsecutiveRegs(0),
- IsCopyElisionCandidate(0), ByValSize(0) {
- static_assert(sizeof(*this) == 2 * sizeof(unsigned), "flags are too big");
+ IsCopyElisionCandidate(0), IsPointer(0), ByValSize(0),
+ PointerAddrSpace(0) {
+ static_assert(sizeof(*this) == 3 * sizeof(unsigned), "flags are too big");
}
bool isZExt() const { return IsZExt; }
@@ -114,6 +117,9 @@ namespace ISD {
bool isCopyElisionCandidate() const { return IsCopyElisionCandidate; }
void setCopyElisionCandidate() { IsCopyElisionCandidate = 1; }
+ bool isPointer() const { return IsPointer; }
+ void setPointer() { IsPointer = 1; }
+
unsigned getByValAlign() const { return (1U << ByValAlign) / 2; }
void setByValAlign(unsigned A) {
ByValAlign = Log2_32(A) + 1;
@@ -128,7 +134,10 @@ namespace ISD {
unsigned getByValSize() const { return ByValSize; }
void setByValSize(unsigned S) { ByValSize = S; }
- };
+
+ unsigned getPointerAddrSpace() const { return PointerAddrSpace; }
+ void setPointerAddrSpace(unsigned AS) { PointerAddrSpace = AS; }
+};
/// InputArg - This struct carries flags and type information about a
/// single incoming (formal) argument or incoming (from the perspective
diff --git a/include/llvm/CodeGen/TargetFrameLowering.h b/include/llvm/CodeGen/TargetFrameLowering.h
index b4d1da941433..878c9ffd2b51 100644
--- a/include/llvm/CodeGen/TargetFrameLowering.h
+++ b/include/llvm/CodeGen/TargetFrameLowering.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/TargetFrameLowering.h ----------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -15,6 +14,7 @@
#define LLVM_CODEGEN_TARGETFRAMELOWERING_H
#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/ADT/StringSwitch.h"
#include <utility>
#include <vector>
@@ -24,6 +24,14 @@ namespace llvm {
class MachineFunction;
class RegScavenger;
+namespace TargetStackID {
+ enum Value {
+ Default = 0,
+ SGPRSpill = 1,
+ NoAlloc = 255
+ };
+}
+
/// Information about stack frame layout on the target. It holds the direction
/// of stack growth, the known stack alignment on entry to each function, and
/// the offset to the locals area.
@@ -262,6 +270,17 @@ public:
return getFrameIndexReference(MF, FI, FrameReg);
}
+ /// getNonLocalFrameIndexReference - This method returns the offset used to
+ /// reference a frame index location. The offset can be from either FP/BP/SP
+ /// based on which base register is returned by llvm.localaddress.
+ virtual int getNonLocalFrameIndexReference(const MachineFunction &MF,
+ int FI) const {
+ // By default, dispatch to getFrameIndexReference. Interested targets can
+ // override this.
+ unsigned FrameReg;
+ return getFrameIndexReference(MF, FI, FrameReg);
+ }
+
/// This method determines which of the registers reported by
/// TargetRegisterInfo::getCalleeSavedRegs() should actually get saved.
/// The default implementation checks populates the \p SavedRegs bitset with
@@ -335,6 +354,16 @@ public:
return true;
}
+ virtual bool isSupportedStackID(TargetStackID::Value ID) const {
+ switch (ID) {
+ default:
+ return false;
+ case TargetStackID::Default:
+ case TargetStackID::NoAlloc:
+ return true;
+ }
+ }
+
/// Check if given function is safe for not having callee saved registers.
/// This is used when interprocedural register allocation is enabled.
static bool isSafeForNoCSROpt(const Function &F) {
diff --git a/include/llvm/CodeGen/TargetInstrInfo.h b/include/llvm/CodeGen/TargetInstrInfo.h
index 961b90e9bc12..25b04f8c019a 100644
--- a/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/include/llvm/CodeGen/TargetInstrInfo.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/TargetInstrInfo.h - Instruction Info --------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -27,6 +26,7 @@
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineOutliner.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/CodeGen/VirtRegMap.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/ErrorHandling.h"
@@ -81,6 +81,7 @@ public:
/// Given a machine instruction descriptor, returns the register
/// class constraint for OpNum, or NULL.
+ virtual
const TargetRegisterClass *getRegClass(const MCInstrDesc &MCID, unsigned OpNum,
const TargetRegisterInfo *TRI,
const MachineFunction &MF) const;
@@ -429,6 +430,13 @@ public:
RegSubRegPair(unsigned Reg = 0, unsigned SubReg = 0)
: Reg(Reg), SubReg(SubReg) {}
+
+ bool operator==(const RegSubRegPair& P) const {
+ return Reg == P.Reg && SubReg == P.SubReg;
+ }
+ bool operator!=(const RegSubRegPair& P) const {
+ return !(*this == P);
+ }
};
/// A pair composed of a pair of a register and a sub-register index,
@@ -663,8 +671,9 @@ public:
/// is finished. Return the value/register of the new loop count. We need
/// this function when peeling off one or more iterations of a loop. This
/// function assumes the nth iteration is peeled first.
- virtual unsigned reduceLoopCount(MachineBasicBlock &MBB, MachineInstr *IndVar,
- MachineInstr &Cmp,
+ virtual unsigned reduceLoopCount(MachineBasicBlock &MBB,
+ MachineBasicBlock &PreHeader,
+ MachineInstr *IndVar, MachineInstr &Cmp,
SmallVectorImpl<MachineOperand> &Cond,
SmallVectorImpl<MachineInstr *> &PrevInsts,
unsigned Iter, unsigned MaxIter) const {
@@ -926,9 +935,12 @@ public:
/// operand folded, otherwise NULL is returned.
/// The new instruction is inserted before MI, and the client is responsible
/// for removing the old instruction.
+ /// If VRM is passed, the assigned physregs can be inspected by target to
+ /// decide on using an opcode (note that those assignments can still change).
MachineInstr *foldMemoryOperand(MachineInstr &MI, ArrayRef<unsigned> Ops,
int FI,
- LiveIntervals *LIS = nullptr) const;
+ LiveIntervals *LIS = nullptr,
+ VirtRegMap *VRM = nullptr) const;
/// Same as the previous version except it allows folding of any load and
/// store from / to any address, not just from a specific stack slot.
@@ -1018,7 +1030,8 @@ protected:
foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI,
ArrayRef<unsigned> Ops,
MachineBasicBlock::iterator InsertPt, int FrameIndex,
- LiveIntervals *LIS = nullptr) const {
+ LiveIntervals *LIS = nullptr,
+ VirtRegMap *VRM = nullptr) const {
return nullptr;
}
@@ -1138,8 +1151,9 @@ public:
/// Get the base operand and byte offset of an instruction that reads/writes
/// memory.
- virtual bool getMemOperandWithOffset(MachineInstr &MI,
- MachineOperand *&BaseOp, int64_t &Offset,
+ virtual bool getMemOperandWithOffset(const MachineInstr &MI,
+ const MachineOperand *&BaseOp,
+ int64_t &Offset,
const TargetRegisterInfo *TRI) const {
return false;
}
@@ -1164,8 +1178,8 @@ public:
/// or
/// DAG->addMutation(createStoreClusterDAGMutation(DAG->TII, DAG->TRI));
/// to TargetPassConfig::createMachineScheduler() to have an effect.
- virtual bool shouldClusterMemOps(MachineOperand &BaseOp1,
- MachineOperand &BaseOp2,
+ virtual bool shouldClusterMemOps(const MachineOperand &BaseOp1,
+ const MachineOperand &BaseOp2,
unsigned NumLoads) const {
llvm_unreachable("target did not implement shouldClusterMemOps()");
}
@@ -1253,8 +1267,9 @@ public:
/// Measure the specified inline asm to determine an approximation of its
/// length.
- virtual unsigned getInlineAsmLength(const char *Str,
- const MCAsmInfo &MAI) const;
+ virtual unsigned getInlineAsmLength(
+ const char *Str, const MCAsmInfo &MAI,
+ const TargetSubtargetInfo *STI = nullptr) const;
/// Allocate and return a hazard recognizer to use for this target when
/// scheduling the machine instructions before register allocation.
@@ -1542,7 +1557,8 @@ public:
/// See also MachineInstr::mayAlias, which is implemented on top of this
/// function.
virtual bool
- areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb,
+ areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
+ const MachineInstr &MIb,
AliasAnalysis *AA = nullptr) const {
assert((MIa.mayLoad() || MIa.mayStore()) &&
"MIa must load from or modify a memory location");
diff --git a/include/llvm/CodeGen/TargetLowering.h b/include/llvm/CodeGen/TargetLowering.h
index 23dbaac03ebe..d5cca60bb1b2 100644
--- a/include/llvm/CodeGen/TargetLowering.h
+++ b/include/llvm/CodeGen/TargetLowering.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/TargetLowering.h - Target Lowering Info -----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
@@ -189,13 +188,18 @@ public:
bool IsSwiftSelf : 1;
bool IsSwiftError : 1;
uint16_t Alignment = 0;
+ Type *ByValType = nullptr;
ArgListEntry()
: IsSExt(false), IsZExt(false), IsInReg(false), IsSRet(false),
IsNest(false), IsByVal(false), IsInAlloca(false), IsReturned(false),
IsSwiftSelf(false), IsSwiftError(false) {}
- void setAttributes(ImmutableCallSite *CS, unsigned ArgIdx);
+ void setAttributes(const CallBase *Call, unsigned ArgIdx);
+
+ void setAttributes(ImmutableCallSite *CS, unsigned ArgIdx) {
+ return setAttributes(cast<CallBase>(CS->getInstruction()), ArgIdx);
+ }
};
using ArgListTy = std::vector<ArgListEntry>;
@@ -235,7 +239,14 @@ public:
/// Return the pointer type for the given address space, defaults to
/// the pointer type from the data layout.
/// FIXME: The default needs to be removed once all the code is updated.
- MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const {
+ virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const {
+ return MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
+ }
+
+ /// Return the in-memory pointer type for the given address space, defaults to
+ /// the pointer type from the data layout. FIXME: The default needs to be
+ /// removed once all the code is updated.
+ MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const {
return MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
}
@@ -291,6 +302,9 @@ public:
// The default action for one element vectors is to scalarize
if (VT.getVectorNumElements() == 1)
return TypeScalarizeVector;
+ // The default action for an odd-width vector is to widen.
+ if (!VT.isPow2VectorType())
+ return TypeWidenVector;
// The default action for other vectors is to promote
return TypePromoteInteger;
}
@@ -387,8 +401,9 @@ public:
/// efficiently, casting the load to a smaller vector of larger types and
/// loading is more efficient, however, this can be undone by optimizations in
/// dag combiner.
- virtual bool isLoadBitCastBeneficial(EVT LoadVT,
- EVT BitcastVT) const {
+ virtual bool isLoadBitCastBeneficial(EVT LoadVT, EVT BitcastVT,
+ const SelectionDAG &DAG,
+ const MachineMemOperand &MMO) const {
// Don't do if we could do an indexed load on the original type, but not on
// the new one.
if (!LoadVT.isSimple() || !BitcastVT.isSimple())
@@ -402,14 +417,18 @@ public:
getTypeToPromoteTo(ISD::LOAD, LoadMVT) == BitcastVT.getSimpleVT())
return false;
- return true;
+ bool Fast = false;
+ return allowsMemoryAccess(*DAG.getContext(), DAG.getDataLayout(), BitcastVT,
+ MMO, &Fast) && Fast;
}
/// Return true if the following transform is beneficial:
/// (store (y (conv x)), y*)) -> (store x, (x*))
- virtual bool isStoreBitCastBeneficial(EVT StoreVT, EVT BitcastVT) const {
+ virtual bool isStoreBitCastBeneficial(EVT StoreVT, EVT BitcastVT,
+ const SelectionDAG &DAG,
+ const MachineMemOperand &MMO) const {
// Default to the same logic as loads.
- return isLoadBitCastBeneficial(StoreVT, BitcastVT);
+ return isLoadBitCastBeneficial(StoreVT, BitcastVT, DAG, MMO);
}
/// Return true if it is expected to be cheaper to do a store of a non-zero
@@ -421,10 +440,12 @@ public:
return false;
}
- /// Allow store merging after legalization in addition to before legalization.
- /// This may catch stores that do not exist earlier (eg, stores created from
- /// intrinsics).
- virtual bool mergeStoresAfterLegalization() const { return true; }
+ /// Allow store merging for the specified type after legalization in addition
+ /// to before legalization. This may transform stores that do not exist
+ /// earlier (for example, stores created from intrinsics).
+ virtual bool mergeStoresAfterLegalization(EVT MemVT) const {
+ return true;
+ }
/// Returns if it's reasonable to merge stores to MemVT size.
virtual bool canMergeStoresTo(unsigned AS, EVT MemVT,
@@ -521,13 +542,22 @@ public:
/// There are two ways to clear extreme bits (either low or high):
/// Mask: x & (-1 << y) (the instcombine canonical form)
/// Shifts: x >> y << y
- /// Return true if the variant with 2 shifts is preferred.
+ /// Return true if the variant with 2 variable shifts is preferred.
/// Return false if there is no preference.
- virtual bool preferShiftsToClearExtremeBits(SDValue X) const {
+ virtual bool shouldFoldMaskToVariableShiftPair(SDValue X) const {
// By default, let's assume that no one prefers shifts.
return false;
}
+ /// Return true if it is profitable to fold a pair of shifts into a mask.
+ /// This is usually true on most targets. But some targets, like Thumb1,
+ /// have immediate shift instructions, but no immediate "and" instruction;
+ /// this makes the fold unprofitable.
+ virtual bool shouldFoldConstantShiftPairToMask(const SDNode *N,
+ CombineLevel Level) const {
+ return true;
+ }
+
/// Should we tranform the IR-optimal check for whether given truncation
/// down into KeptBits would be truncating or not:
/// (add %x, (1 << (KeptBits-1))) srccond (1 << KeptBits)
@@ -541,6 +571,16 @@ public:
return false;
}
+ /// These two forms are equivalent:
+ /// sub %y, (xor %x, -1)
+ /// add (add %x, 1), %y
+ /// The variant with two add's is IR-canonical.
+ /// Some targets may prefer one to the other.
+ virtual bool preferIncOfAddToSubOfNot(EVT VT) const {
+ // By default, let's assume that everyone prefers the form with two add's.
+ return true;
+ }
+
/// Return true if the target wants to use the optimization that
/// turns ext(promotableInst1(...(promotableInstN(load)))) into
/// promotedInst1(...(promotedInstN(ext(load)))).
@@ -560,11 +600,6 @@ public:
return false;
}
- /// Return true if target supports floating point exceptions.
- bool hasFloatingPointExceptions() const {
- return HasFloatingPointExceptions;
- }
-
/// Return true if target always beneficiates from combining into FMA for a
/// given value type. This must typically return false on targets where FMA
/// takes more cycles to execute than FADD.
@@ -619,12 +654,21 @@ public:
/// Return the register class that should be used for the specified value
/// type.
- virtual const TargetRegisterClass *getRegClassFor(MVT VT) const {
+ virtual const TargetRegisterClass *getRegClassFor(MVT VT, bool isDivergent = false) const {
+ (void)isDivergent;
const TargetRegisterClass *RC = RegClassForVT[VT.SimpleTy];
assert(RC && "This value type is not natively supported!");
return RC;
}
+ /// Allows target to decide about the register class of the
+ /// specific value that is live outside the defining block.
+ /// Returns true if the value needs uniform register class.
+ virtual bool requiresUniformRegister(MachineFunction &MF,
+ const Value *) const {
+ return false;
+ }
+
/// Return the 'representative' register class for the specified value
/// type.
///
@@ -643,6 +687,13 @@ public:
return RepRegClassCostForVT[VT.SimpleTy];
}
+ /// Return true if SHIFT instructions should be expanded to SHIFT_PARTS
+ /// instructions, and false if a library call is preferred (e.g for code-size
+ /// reasons).
+ virtual bool shouldExpandShift(SelectionDAG &DAG, SDNode *N) const {
+ return true;
+ }
+
/// Return true if the target has native support for the specified value type.
/// This means that it has a register that directly holds it without
/// promotions or expansions.
@@ -768,7 +819,8 @@ public:
/// Returns true if the target can instruction select the specified FP
/// immediate natively. If false, the legalizer will materialize the FP
/// immediate as a load from a constant pool.
- virtual bool isFPImmLegal(const APFloat &/*Imm*/, EVT /*VT*/) const {
+ virtual bool isFPImmLegal(const APFloat & /*Imm*/, EVT /*VT*/,
+ bool ForCodeSize = false) const {
return false;
}
@@ -830,6 +882,8 @@ public:
default:
llvm_unreachable("Unexpected fixed point operation.");
case ISD::SMULFIX:
+ case ISD::SMULFIXSAT:
+ case ISD::UMULFIX:
Supported = isSupportedFixedPointOperation(Op, VT, Scale);
break;
}
@@ -865,6 +919,8 @@ public:
case ISD::STRICT_FFLOOR: EqOpc = ISD::FFLOOR; break;
case ISD::STRICT_FROUND: EqOpc = ISD::FROUND; break;
case ISD::STRICT_FTRUNC: EqOpc = ISD::FTRUNC; break;
+ case ISD::STRICT_FP_ROUND: EqOpc = ISD::FP_ROUND; break;
+ case ISD::STRICT_FP_EXTEND: EqOpc = ISD::FP_EXTEND; break;
}
auto Action = getOperationAction(EqOpc, VT);
@@ -931,21 +987,20 @@ public:
/// Return true if lowering to a jump table is suitable for a set of case
/// clusters which may contain \p NumCases cases, \p Range range of values.
- /// FIXME: This function check the maximum table size and density, but the
- /// minimum size is not checked. It would be nice if the minimum size is
- /// also combined within this function. Currently, the minimum size check is
- /// performed in findJumpTable() in SelectionDAGBuiler and
- /// getEstimatedNumberOfCaseClusters() in BasicTTIImpl.
virtual bool isSuitableForJumpTable(const SwitchInst *SI, uint64_t NumCases,
uint64_t Range) const {
- const bool OptForSize = SI->getParent()->getParent()->optForSize();
+ // FIXME: This function check the maximum table size and density, but the
+ // minimum size is not checked. It would be nice if the minimum size is
+ // also combined within this function. Currently, the minimum size check is
+ // performed in findJumpTable() in SelectionDAGBuiler and
+ // getEstimatedNumberOfCaseClusters() in BasicTTIImpl.
+ const bool OptForSize = SI->getParent()->getParent()->hasOptSize();
const unsigned MinDensity = getMinimumJumpTableDensity(OptForSize);
- const unsigned MaxJumpTableSize =
- OptForSize || getMaximumJumpTableSize() == 0
- ? UINT_MAX
- : getMaximumJumpTableSize();
- // Check whether a range of clusters is dense enough for a jump table.
- if (Range <= MaxJumpTableSize &&
+ const unsigned MaxJumpTableSize = getMaximumJumpTableSize();
+
+ // Check whether the number of cases is small enough and
+ // the range is dense enough for a jump table.
+ if ((OptForSize || Range <= MaxJumpTableSize) &&
(NumCases * 100 >= Range * MinDensity)) {
return true;
}
@@ -1140,24 +1195,42 @@ public:
EVT getValueType(const DataLayout &DL, Type *Ty,
bool AllowUnknown = false) const {
// Lower scalar pointers to native pointer types.
- if (PointerType *PTy = dyn_cast<PointerType>(Ty))
+ if (auto *PTy = dyn_cast<PointerType>(Ty))
return getPointerTy(DL, PTy->getAddressSpace());
- if (Ty->isVectorTy()) {
- VectorType *VTy = cast<VectorType>(Ty);
- Type *Elm = VTy->getElementType();
+ if (auto *VTy = dyn_cast<VectorType>(Ty)) {
+ Type *EltTy = VTy->getElementType();
// Lower vectors of pointers to native pointer types.
+ if (auto *PTy = dyn_cast<PointerType>(EltTy)) {
+ EVT PointerTy(getPointerTy(DL, PTy->getAddressSpace()));
+ EltTy = PointerTy.getTypeForEVT(Ty->getContext());
+ }
+ return EVT::getVectorVT(Ty->getContext(), EVT::getEVT(EltTy, false),
+ VTy->getNumElements());
+ }
+
+ return EVT::getEVT(Ty, AllowUnknown);
+ }
+
+ EVT getMemValueType(const DataLayout &DL, Type *Ty,
+ bool AllowUnknown = false) const {
+ // Lower scalar pointers to native pointer types.
+ if (PointerType *PTy = dyn_cast<PointerType>(Ty))
+ return getPointerMemTy(DL, PTy->getAddressSpace());
+ else if (VectorType *VTy = dyn_cast<VectorType>(Ty)) {
+ Type *Elm = VTy->getElementType();
if (PointerType *PT = dyn_cast<PointerType>(Elm)) {
- EVT PointerTy(getPointerTy(DL, PT->getAddressSpace()));
+ EVT PointerTy(getPointerMemTy(DL, PT->getAddressSpace()));
Elm = PointerTy.getTypeForEVT(Ty->getContext());
}
-
return EVT::getVectorVT(Ty->getContext(), EVT::getEVT(Elm, false),
VTy->getNumElements());
}
- return EVT::getEVT(Ty, AllowUnknown);
+
+ return getValueType(DL, Ty, AllowUnknown);
}
+
/// Return the MVT corresponding to this LLVM type. See getValueType.
MVT getSimpleValueType(const DataLayout &DL, Type *Ty,
bool AllowUnknown = false) const {
@@ -1327,18 +1400,6 @@ public:
return OptSize ? MaxLoadsPerMemcmpOptSize : MaxLoadsPerMemcmp;
}
- /// For memcmp expansion when the memcmp result is only compared equal or
- /// not-equal to 0, allow up to this number of load pairs per block. As an
- /// example, this may allow 'memcmp(a, b, 3) == 0' in a single block:
- /// a0 = load2bytes &a[0]
- /// b0 = load2bytes &b[0]
- /// a2 = load1byte &a[2]
- /// b2 = load1byte &b[2]
- /// r = cmp eq (a0 ^ b0 | a2 ^ b2), 0
- virtual unsigned getMemcmpEqZeroLoadsPerBlock() const {
- return 1;
- }
-
/// Get maximum # of store operations permitted for llvm.memmove
///
/// This function returns the maximum number of store operations permitted
@@ -1358,10 +1419,10 @@ public:
/// copy/move/set is converted to a sequence of store operations. Its use
/// helps to ensure that such replacements don't generate code that causes an
/// alignment error (trap) on the target machine.
- virtual bool allowsMisalignedMemoryAccesses(EVT,
- unsigned AddrSpace = 0,
- unsigned Align = 1,
- bool * /*Fast*/ = nullptr) const {
+ virtual bool allowsMisalignedMemoryAccesses(
+ EVT, unsigned AddrSpace = 0, unsigned Align = 1,
+ MachineMemOperand::Flags Flags = MachineMemOperand::MONone,
+ bool * /*Fast*/ = nullptr) const {
return false;
}
@@ -1369,8 +1430,18 @@ public:
/// given address space and alignment. If the access is allowed, the optional
/// final parameter returns if the access is also fast (as defined by the
/// target).
+ bool
+ allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT,
+ unsigned AddrSpace = 0, unsigned Alignment = 1,
+ MachineMemOperand::Flags Flags = MachineMemOperand::MONone,
+ bool *Fast = nullptr) const;
+
+ /// Return true if the target supports a memory access of this type for the
+ /// given MachineMemOperand. If the access is allowed, the optional
+ /// final parameter returns if the access is also fast (as defined by the
+ /// target).
bool allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT,
- unsigned AddrSpace = 0, unsigned Alignment = 1,
+ const MachineMemOperand &MMO,
bool *Fast = nullptr) const;
/// Returns the target specific optimal type for load and store operations as
@@ -1384,12 +1455,11 @@ public:
/// zero. 'MemcpyStrSrc' indicates whether the memcpy source is constant so it
/// does not need to be loaded. It returns EVT::Other if the type should be
/// determined using generic target-independent logic.
- virtual EVT getOptimalMemOpType(uint64_t /*Size*/,
- unsigned /*DstAlign*/, unsigned /*SrcAlign*/,
- bool /*IsMemset*/,
- bool /*ZeroMemset*/,
- bool /*MemcpyStrSrc*/,
- MachineFunction &/*MF*/) const {
+ virtual EVT
+ getOptimalMemOpType(uint64_t /*Size*/, unsigned /*DstAlign*/,
+ unsigned /*SrcAlign*/, bool /*IsMemset*/,
+ bool /*ZeroMemset*/, bool /*MemcpyStrSrc*/,
+ const AttributeList & /*FuncAttributes*/) const {
return MVT::Other;
}
@@ -1515,7 +1585,7 @@ public:
/// performs validation and error handling, returns the function. Otherwise,
/// returns nullptr. Must be previously inserted by insertSSPDeclarations.
/// Should be used only when getIRStackGuard returns nullptr.
- virtual Value *getSSPStackGuardCheck(const Module &M) const;
+ virtual Function *getSSPStackGuardCheck(const Module &M) const;
protected:
Value *getDefaultSafeStackPointerLocation(IRBuilder<> &IRB,
@@ -1537,8 +1607,9 @@ public:
}
/// Returns true if a cast from SrcAS to DestAS is "cheap", such that e.g. we
- /// are happy to sink it into basic blocks.
- virtual bool isCheapAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const {
+ /// are happy to sink it into basic blocks. A cast may be free, but not
+ /// necessarily a no-op. e.g. a free truncate from a 64-bit to 32-bit pointer.
+ virtual bool isFreeAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const {
return isNoopAddrSpaceCast(SrcAS, DestAS);
}
@@ -1716,8 +1787,9 @@ public:
/// Returns how the IR-level AtomicExpand pass should expand the given
/// AtomicRMW, if at all. Default is to never expand.
- virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *) const {
- return AtomicExpansionKind::None;
+ virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const {
+ return RMW->isFloatingPointOperation() ?
+ AtomicExpansionKind::CmpXChg : AtomicExpansionKind::None;
}
/// On some platforms, an AtomicRMW that never actually modifies the value
@@ -1762,6 +1834,8 @@ public:
Action != TypeSplitVector;
}
+ virtual bool isProfitableToCombineMinNumMaxNum(EVT VT) const { return true; }
+
/// Return true if a select of constants (select Cond, C1, C2) should be
/// transformed into simple math ops with the condition value. For example:
/// select Cond, C1, C1-1 --> add (zext Cond), C1-1
@@ -1865,12 +1939,6 @@ protected:
/// control.
void setJumpIsExpensive(bool isExpensive = true);
- /// Tells the code generator that this target supports floating point
- /// exceptions and cares about preserving floating point exception behavior.
- void setHasFloatingPointExceptions(bool FPExceptions = true) {
- HasFloatingPointExceptions = FPExceptions;
- }
-
/// Tells the code generator which bitwidths to bypass.
void addBypassSlowDiv(unsigned int SlowBitWidth, unsigned int FastBitWidth) {
BypassSlowDivWidths[SlowBitWidth] = FastBitWidth;
@@ -2159,6 +2227,8 @@ public:
case ISD::UADDSAT:
case ISD::FMINNUM:
case ISD::FMAXNUM:
+ case ISD::FMINNUM_IEEE:
+ case ISD::FMAXNUM_IEEE:
case ISD::FMINIMUM:
case ISD::FMAXIMUM:
return true;
@@ -2166,6 +2236,30 @@ public:
}
}
+ /// Return true if the node is a math/logic binary operator.
+ virtual bool isBinOp(unsigned Opcode) const {
+ // A commutative binop must be a binop.
+ if (isCommutativeBinOp(Opcode))
+ return true;
+ // These are non-commutative binops.
+ switch (Opcode) {
+ case ISD::SUB:
+ case ISD::SHL:
+ case ISD::SRL:
+ case ISD::SRA:
+ case ISD::SDIV:
+ case ISD::UDIV:
+ case ISD::SREM:
+ case ISD::UREM:
+ case ISD::FSUB:
+ case ISD::FDIV:
+ case ISD::FREM:
+ return true;
+ default:
+ return false;
+ }
+ }
+
/// Return true if it's free to truncate a value of type FromTy to type
/// ToTy. e.g. On x86 it's free to truncate a i32 value in register EAX to i16
/// by referencing its sub-register AX.
@@ -2270,6 +2364,16 @@ public:
return false;
}
+ /// Return true if sinking I's operands to the same basic block as I is
+ /// profitable, e.g. because the operands can be folded into a target
+ /// instruction during instruction selection. After calling the function
+ /// \p Ops contains the Uses to sink ordered by dominance (dominating users
+ /// come first).
+ virtual bool shouldSinkOperands(Instruction *I,
+ SmallVectorImpl<Use *> &Ops) const {
+ return false;
+ }
+
/// Return true if the target supplies and combines to a paired load
/// two loaded values of type LoadedType next to each other in memory.
/// RequiredAlignment gives the minimal alignment constraints that must be met
@@ -2415,6 +2519,31 @@ public:
return false;
}
+ /// Return true if extraction of a scalar element from the given vector type
+ /// at the given index is cheap. For example, if scalar operations occur on
+ /// the same register file as vector operations, then an extract element may
+ /// be a sub-register rename rather than an actual instruction.
+ virtual bool isExtractVecEltCheap(EVT VT, unsigned Index) const {
+ return false;
+ }
+
+ /// Try to convert math with an overflow comparison into the corresponding DAG
+ /// node operation. Targets may want to override this independently of whether
+ /// the operation is legal/custom for the given type because it may obscure
+ /// matching of other patterns.
+ virtual bool shouldFormOverflowOp(unsigned Opcode, EVT VT) const {
+ // TODO: The default logic is inherited from code in CodeGenPrepare.
+ // The opcode should not make a difference by default?
+ if (Opcode != ISD::UADDO)
+ return false;
+
+ // Allow the transform as long as we have an integer type that is not
+ // obviously illegal and unsupported.
+ if (VT.isVector())
+ return false;
+ return VT.isSimple() || !isOperationExpand(Opcode, VT);
+ }
+
// Return true if it is profitable to use a scalar input to a BUILD_VECTOR
// even if the vector itself has multiple uses.
virtual bool aggressivelyPreferBuildVectorSources(EVT VecVT) const {
@@ -2495,10 +2624,6 @@ private:
/// predication.
bool JumpIsExpensive;
- /// Whether the target supports or cares about preserving floating point
- /// exception behavior.
- bool HasFloatingPointExceptions;
-
/// This target prefers to use _setjmp to implement llvm.setjmp.
///
/// Defaults to false.
@@ -2834,11 +2959,10 @@ public:
/// Returns a pair of (return value, chain).
/// It is an error to pass RTLIB::UNKNOWN_LIBCALL as \p LC.
- std::pair<SDValue, SDValue> makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC,
- EVT RetVT, ArrayRef<SDValue> Ops,
- bool isSigned, const SDLoc &dl,
- bool doesNotReturn = false,
- bool isReturnValueUsed = true) const;
+ std::pair<SDValue, SDValue> makeLibCall(
+ SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef<SDValue> Ops,
+ bool isSigned, const SDLoc &dl, bool doesNotReturn = false,
+ bool isReturnValueUsed = true, bool isPostTypeLegalization = false) const;
/// Check whether parameters to a call that are passed in callee saved
/// registers are the same as from the calling function. This needs to be
@@ -2876,6 +3000,20 @@ public:
}
};
+ /// Determines the optimal series of memory ops to replace the memset / memcpy.
+ /// Return true if the number of memory ops is below the threshold (Limit).
+ /// It returns the types of the sequence of memory ops to perform
+ /// memset / memcpy by reference.
+ bool findOptimalMemOpLowering(std::vector<EVT> &MemOps,
+ unsigned Limit, uint64_t Size,
+ unsigned DstAlign, unsigned SrcAlign,
+ bool IsMemset,
+ bool ZeroMemset,
+ bool MemcpyStrSrc,
+ bool AllowOverlap,
+ unsigned DstAS, unsigned SrcAS,
+ const AttributeList &FuncAttributes) const;
+
/// Check to see if the specified operand of the specified instruction is a
/// constant integer. If so, check to see if there are any bits set in the
/// constant that are not demanded. If so, shrink the constant and return
@@ -3001,6 +3139,10 @@ public:
TargetLoweringOpt &TLO,
unsigned Depth = 0) const;
+ /// This method returns the constant pool value that will be loaded by LD.
+ /// NOTE: You must check for implicit extensions of the constant by LD.
+ virtual const Constant *getTargetConstantFromLoad(LoadSDNode *LD) const;
+
/// If \p SNaN is false, \returns true if \p Op is known to never be any
/// NaN. If \p sNaN is true, returns if \p Op is known to never be a signaling
/// NaN.
@@ -3088,15 +3230,6 @@ public:
return true;
}
- /// Return true if it is profitable to fold a pair of shifts into a mask.
- /// This is usually true on most targets. But some targets, like Thumb1,
- /// have immediate shift instructions, but no immediate "and" instruction;
- /// this makes the fold unprofitable.
- virtual bool shouldFoldShiftPairToMask(const SDNode *N,
- CombineLevel Level) const {
- return true;
- }
-
// Return true if it is profitable to combine a BUILD_VECTOR with a stride-pattern
// to a shuffle and a truncate.
// Example of such a combine:
@@ -3430,6 +3563,15 @@ public:
return false;
}
+ /// For most targets, an LLVM type must be broken down into multiple
+ /// smaller types. Usually the halves are ordered according to the endianness
+ /// but for some platform that would break. So this method will default to
+ /// matching the endianness but can be overridden.
+ virtual bool
+ shouldSplitFunctionArgumentsAsLittleEndian(const DataLayout &DL) const {
+ return DL.isLittleEndian();
+ }
+
/// Returns a 0 terminated array of registers that can be safely used as
/// scratch registers.
virtual const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const {
@@ -3638,6 +3780,12 @@ public:
std::vector<SDValue> &Ops,
SelectionDAG &DAG) const;
+ // Lower custom output constraints. If invalid, return SDValue().
+ virtual SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue &Flag,
+ SDLoc DL,
+ const AsmOperandInfo &OpInfo,
+ SelectionDAG &DAG) const;
+
//===--------------------------------------------------------------------===//
// Div utility functions
//
@@ -3840,8 +3988,26 @@ public:
/// Method for building the DAG expansion of ISD::SMULFIX. This method accepts
/// integers as its arguments.
- SDValue getExpandedFixedPointMultiplication(SDNode *Node,
- SelectionDAG &DAG) const;
+ SDValue expandFixedPointMul(SDNode *Node, SelectionDAG &DAG) const;
+
+ /// Method for building the DAG expansion of ISD::U(ADD|SUB)O. Expansion
+ /// always suceeds and populates the Result and Overflow arguments.
+ void expandUADDSUBO(SDNode *Node, SDValue &Result, SDValue &Overflow,
+ SelectionDAG &DAG) const;
+
+ /// Method for building the DAG expansion of ISD::S(ADD|SUB)O. Expansion
+ /// always suceeds and populates the Result and Overflow arguments.
+ void expandSADDSUBO(SDNode *Node, SDValue &Result, SDValue &Overflow,
+ SelectionDAG &DAG) const;
+
+ /// Method for building the DAG expansion of ISD::[US]MULO. Returns whether
+ /// expansion was successful and populates the Result and Overflow arguments.
+ bool expandMULO(SDNode *Node, SDValue &Result, SDValue &Overflow,
+ SelectionDAG &DAG) const;
+
+ /// Expand a VECREDUCE_* into an explicit calculation. If Count is specified,
+ /// only the first Count elements of the vector are used.
+ SDValue expandVecReduce(SDNode *Node, SelectionDAG &DAG) const;
//===--------------------------------------------------------------------===//
// Instruction Emitting Hooks
@@ -3894,14 +4060,23 @@ public:
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const;
private:
- SDValue simplifySetCCWithAnd(EVT VT, SDValue N0, SDValue N1,
- ISD::CondCode Cond, DAGCombinerInfo &DCI,
- const SDLoc &DL) const;
+ SDValue foldSetCCWithAnd(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond,
+ const SDLoc &DL, DAGCombinerInfo &DCI) const;
+ SDValue foldSetCCWithBinOp(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond,
+ const SDLoc &DL, DAGCombinerInfo &DCI) const;
SDValue optimizeSetCCOfSignedTruncationCheck(EVT SCCVT, SDValue N0,
SDValue N1, ISD::CondCode Cond,
DAGCombinerInfo &DCI,
const SDLoc &DL) const;
+
+ SDValue prepareUREMEqFold(EVT SETCCVT, SDValue REMNode,
+ SDValue CompTargetNode, ISD::CondCode Cond,
+ DAGCombinerInfo &DCI, const SDLoc &DL,
+ SmallVectorImpl<SDNode *> &Created) const;
+ SDValue buildUREMEqFold(EVT SETCCVT, SDValue REMNode, SDValue CompTargetNode,
+ ISD::CondCode Cond, DAGCombinerInfo &DCI,
+ const SDLoc &DL) const;
};
/// Given an LLVM IR type and return type attributes, compute the return value
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 052d1f8bc686..a1fb81cb009d 100644
--- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -1,9 +1,8 @@
//==- llvm/CodeGen/TargetLoweringObjectFileImpl.h - Object Info --*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/TargetOpcodes.h b/include/llvm/CodeGen/TargetOpcodes.h
index d0d959c4ae11..080a244f6f69 100644
--- a/include/llvm/CodeGen/TargetOpcodes.h
+++ b/include/llvm/CodeGen/TargetOpcodes.h
@@ -1,9 +1,8 @@
//===-- llvm/CodeGen/TargetOpcodes.h - Target Indep Opcodes -----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/TargetPassConfig.h b/include/llvm/CodeGen/TargetPassConfig.h
index 3288711a335d..0bd82aafac37 100644
--- a/include/llvm/CodeGen/TargetPassConfig.h
+++ b/include/llvm/CodeGen/TargetPassConfig.h
@@ -1,9 +1,8 @@
//===- TargetPassConfig.h - Code Generation pass options --------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -25,6 +24,7 @@ class LLVMTargetMachine;
struct MachineSchedContext;
class PassConfigImpl;
class ScheduleDAGInstrs;
+class CSEConfigBase;
// The old pass manager infrastructure is hidden in a legacy namespace now.
namespace legacy {
@@ -75,9 +75,6 @@ public:
}
};
-template <> struct isPodLike<IdentifyingPassPtr> {
- static const bool value = true;
-};
/// Target-Independent Code Generator Pass Configuration Options.
///
@@ -319,6 +316,13 @@ public:
/// when GlobalISel failed and isGlobalISelAbortEnabled is false.
virtual bool reportDiagnosticWhenGlobalISelFallback() const;
+ /// Check whether continuous CSE should be enabled in GISel passes.
+ /// By default, it's enabled for non O0 levels.
+ virtual bool isGISelCSEEnabled() const;
+
+ /// Returns the CSEConfig object to use for the current optimization level.
+ virtual std::unique_ptr<CSEConfigBase> getCSEConfig() const;
+
protected:
// Helper to verify the analysis is really immutable.
void setOpt(bool &Opt, bool Val);
@@ -360,11 +364,11 @@ protected:
/// addFastRegAlloc - Add the minimum set of target-independent passes that
/// are required for fast register allocation.
- virtual void addFastRegAlloc(FunctionPass *RegAllocPass);
+ virtual void addFastRegAlloc();
/// addOptimizedRegAlloc - Add passes related to register allocation.
/// LLVMTargetMachine provides standard regalloc passes for most targets.
- virtual void addOptimizedRegAlloc(FunctionPass *RegAllocPass);
+ virtual void addOptimizedRegAlloc();
/// addPreRewrite - Add passes to the optimized register allocation pipeline
/// after register allocation is complete, but before virtual registers are
@@ -374,10 +378,18 @@ protected:
/// after RABasic or RAGreedy, they should take advantage of LiveRegMatrix.
/// When these passes run, VirtRegMap contains legal physreg assignments for
/// all virtual registers.
+ ///
+ /// Note if the target overloads addRegAssignAndRewriteOptimized, this may not
+ /// be honored. This is also not generally used for the the fast variant,
+ /// where the allocation and rewriting are done in one pass.
virtual bool addPreRewrite() {
return false;
}
+ /// Add passes to be run immediately after virtual registers are rewritten
+ /// to physical registers.
+ virtual void addPostRewrite() { }
+
/// This method may be implemented by targets that want to run passes after
/// register allocation pass pipeline but before prolog-epilog insertion.
virtual void addPostRegAlloc() { }
@@ -431,7 +443,12 @@ protected:
/// addMachinePasses helper to create the target-selected or overriden
/// regalloc pass.
- FunctionPass *createRegAllocPass(bool Optimized);
+ virtual FunctionPass *createRegAllocPass(bool Optimized);
+
+ /// Add core register alloator passes which do the actual register assignment
+ /// and rewriting. \returns true if any passes were added.
+ virtual bool addRegAssignmentFast();
+ virtual bool addRegAssignmentOptimized();
};
} // end namespace llvm
diff --git a/include/llvm/CodeGen/TargetRegisterInfo.h b/include/llvm/CodeGen/TargetRegisterInfo.h
index 0fbff3137653..ddbd677b3eaa 100644
--- a/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -1,9 +1,8 @@
//==- CodeGen/TargetRegisterInfo.h - Target Register Information -*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -521,6 +520,11 @@ public:
/// function. Used by MachineRegisterInfo::isConstantPhysReg().
virtual bool isConstantPhysReg(unsigned PhysReg) const { return false; }
+ /// Returns true if the register class is considered divergent.
+ virtual bool isDivergentRegClass(const TargetRegisterClass *RC) const {
+ return false;
+ }
+
/// Physical registers that may be modified within a function but are
/// guaranteed to be restored before any uses. This is useful for targets that
/// have call sequences where a GOT register may be updated by the caller
@@ -986,7 +990,7 @@ public:
/// getFrameRegister - This method should return the register used as a base
/// for values allocated in the current stack frame.
- virtual unsigned getFrameRegister(const MachineFunction &MF) const = 0;
+ virtual Register getFrameRegister(const MachineFunction &MF) const = 0;
/// Mark a register and all its aliases as reserved in the given set.
void markSuperRegs(BitVector &RegisterSet, unsigned Reg) const;
diff --git a/include/llvm/CodeGen/TargetSchedule.h b/include/llvm/CodeGen/TargetSchedule.h
index 6173925e23a1..cce85c8d7b0d 100644
--- a/include/llvm/CodeGen/TargetSchedule.h
+++ b/include/llvm/CodeGen/TargetSchedule.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/TargetSchedule.h - Sched Machine Model ------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/TargetSubtargetInfo.h b/include/llvm/CodeGen/TargetSubtargetInfo.h
index 968e4c4b8102..037fc3ed3243 100644
--- a/include/llvm/CodeGen/TargetSubtargetInfo.h
+++ b/include/llvm/CodeGen/TargetSubtargetInfo.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/TargetSubtargetInfo.h - Target Information --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -43,6 +42,7 @@ class RegisterBankInfo;
class SDep;
class SelectionDAGTargetInfo;
struct SubtargetFeatureKV;
+struct SubtargetSubTypeKV;
struct SubtargetInfoKV;
class SUnit;
class TargetFrameLowering;
@@ -63,8 +63,7 @@ class TargetSubtargetInfo : public MCSubtargetInfo {
protected: // Can only create subclasses...
TargetSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS,
ArrayRef<SubtargetFeatureKV> PF,
- ArrayRef<SubtargetFeatureKV> PD,
- const SubtargetInfoKV *ProcSched,
+ ArrayRef<SubtargetSubTypeKV> PD,
const MCWriteProcResEntry *WPR,
const MCWriteLatencyEntry *WL,
const MCReadAdvanceEntry *RA, const InstrStage *IS,
@@ -190,13 +189,13 @@ public:
/// TargetLowering preference). It does not yet disable the postRA scheduler.
virtual bool enableMachineScheduler() const;
- /// Support printing of [latency:throughput] comment in output .S file.
- virtual bool supportPrintSchedInfo() const { return false; }
-
/// True if the machine scheduler should disable the TLI preference
/// for preRA scheduling with the source level scheduler.
virtual bool enableMachineSchedDefaultSched() const { return true; }
+ /// True if the subtarget should run MachinePipeliner
+ virtual bool enableMachinePipeliner() const { return true; };
+
/// True if the subtarget should enable joining global copies.
///
/// By default this is enabled if the machine scheduler is enabled, but
@@ -250,6 +249,10 @@ public:
std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const {
}
+ /// Default to DFA for resource management, return false when target will use
+ /// ProcResource in InstrSchedModel instead.
+ virtual bool useDFAforSMS() const { return true; }
+
// For use with PostRAScheduling: get the minimum optimization level needed
// to enable post-RA scheduling.
virtual CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const {
@@ -286,12 +289,16 @@ public:
/// possible.
virtual bool enableSubRegLiveness() const { return false; }
- /// Returns string representation of scheduler comment
- std::string getSchedInfoStr(const MachineInstr &MI) const;
- std::string getSchedInfoStr(MCInst const &MCI) const override;
-
/// This is called after a .mir file was loaded.
virtual void mirFileLoaded(MachineFunction &MF) const;
+
+ /// True if the register allocator should use the allocation orders exactly as
+ /// written in the tablegen descriptions, false if it should allocate
+ /// the specified physical register later if is it callee-saved.
+ virtual bool ignoreCSRForAllocationOrder(const MachineFunction &MF,
+ unsigned PhysReg) const {
+ return false;
+ }
};
} // end namespace llvm
diff --git a/include/llvm/CodeGen/UnreachableBlockElim.h b/include/llvm/CodeGen/UnreachableBlockElim.h
index 3e7afd4cd433..d52d7c3c5b49 100644
--- a/include/llvm/CodeGen/UnreachableBlockElim.h
+++ b/include/llvm/CodeGen/UnreachableBlockElim.h
@@ -1,9 +1,8 @@
//===-- UnreachableBlockElim.h - Remove unreachable blocks for codegen --===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h
index d2ef4a94f8e2..c540c94f79d9 100644
--- a/include/llvm/CodeGen/ValueTypes.h
+++ b/include/llvm/CodeGen/ValueTypes.h
@@ -1,9 +1,8 @@
//===- CodeGen/ValueTypes.h - Low-Level Target independ. types --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/CodeGen/ValueTypes.td b/include/llvm/CodeGen/ValueTypes.td
index 0abb4ece1d14..5818ac183fcc 100644
--- a/include/llvm/CodeGen/ValueTypes.td
+++ b/include/llvm/CodeGen/ValueTypes.td
@@ -1,9 +1,8 @@
//===- ValueTypes.td - ValueType definitions ---------------*- tablegen -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -63,89 +62,105 @@ def v32i16 : ValueType<512, 38>; // 32 x i16 vector value
def v64i16 : ValueType<1024,39>; // 64 x i16 vector value
def v128i16: ValueType<2048,40>; //128 x i16 vector value
-def v1i32 : ValueType<32 , 41>; // 1 x i32 vector value
-def v2i32 : ValueType<64 , 42>; // 2 x i32 vector value
-def v4i32 : ValueType<128, 43>; // 4 x i32 vector value
-def v8i32 : ValueType<256, 44>; // 8 x i32 vector value
-def v16i32 : ValueType<512, 45>; // 16 x i32 vector value
-def v32i32 : ValueType<1024,46>; // 32 x i32 vector value
-def v64i32 : ValueType<2048,47>; // 64 x i32 vector value
+def v1i32 : ValueType<32 , 41>; // 1 x i32 vector value
+def v2i32 : ValueType<64 , 42>; // 2 x i32 vector value
+def v3i32 : ValueType<96 , 43>; // 3 x i32 vector value
+def v4i32 : ValueType<128, 44>; // 4 x i32 vector value
+def v5i32 : ValueType<160, 45>; // 5 x i32 vector value
+def v8i32 : ValueType<256, 46>; // 8 x i32 vector value
+def v16i32 : ValueType<512, 47>; // 16 x i32 vector value
+def v32i32 : ValueType<1024,48>; // 32 x i32 vector value
+def v64i32 : ValueType<2048,49>; // 64 x i32 vector value
+def v128i32 : ValueType<4096,50>; // 128 x i32 vector value
+def v256i32 : ValueType<8182,51>; // 256 x i32 vector value
+def v512i32 : ValueType<16384,52>; // 512 x i32 vector value
+def v1024i32 : ValueType<32768,53>; // 1024 x i32 vector value
+def v2048i32 : ValueType<65536,54>; // 2048 x i32 vector value
-def v1i64 : ValueType<64 , 48>; // 1 x i64 vector value
-def v2i64 : ValueType<128, 49>; // 2 x i64 vector value
-def v4i64 : ValueType<256, 50>; // 4 x i64 vector value
-def v8i64 : ValueType<512, 51>; // 8 x i64 vector value
-def v16i64 : ValueType<1024,52>; // 16 x i64 vector value
-def v32i64 : ValueType<2048,53>; // 32 x i64 vector value
+def v1i64 : ValueType<64 , 55>; // 1 x i64 vector value
+def v2i64 : ValueType<128, 56>; // 2 x i64 vector value
+def v4i64 : ValueType<256, 57>; // 4 x i64 vector value
+def v8i64 : ValueType<512, 58>; // 8 x i64 vector value
+def v16i64 : ValueType<1024,59>; // 16 x i64 vector value
+def v32i64 : ValueType<2048,60>; // 32 x i64 vector value
-def v1i128 : ValueType<128, 54>; // 1 x i128 vector value
+def v1i128 : ValueType<128, 61>; // 1 x i128 vector value
-def nxv1i1 : ValueType<1, 55>; // n x 1 x i1 vector value
-def nxv2i1 : ValueType<2, 56>; // n x 2 x i1 vector value
-def nxv4i1 : ValueType<4, 57>; // n x 4 x i1 vector value
-def nxv8i1 : ValueType<8, 58>; // n x 8 x i1 vector value
-def nxv16i1 : ValueType<16, 59>; // n x 16 x i1 vector value
-def nxv32i1 : ValueType<32, 60>; // n x 32 x i1 vector value
+def nxv1i1 : ValueType<1, 62>; // n x 1 x i1 vector value
+def nxv2i1 : ValueType<2, 63>; // n x 2 x i1 vector value
+def nxv4i1 : ValueType<4, 64>; // n x 4 x i1 vector value
+def nxv8i1 : ValueType<8, 65>; // n x 8 x i1 vector value
+def nxv16i1 : ValueType<16, 66>; // n x 16 x i1 vector value
+def nxv32i1 : ValueType<32, 67>; // n x 32 x i1 vector value
-def nxv1i8 : ValueType<8, 61>; // n x 1 x i8 vector value
-def nxv2i8 : ValueType<16, 62>; // n x 2 x i8 vector value
-def nxv4i8 : ValueType<32, 63>; // n x 4 x i8 vector value
-def nxv8i8 : ValueType<64, 64>; // n x 8 x i8 vector value
-def nxv16i8 : ValueType<128, 65>; // n x 16 x i8 vector value
-def nxv32i8 : ValueType<256, 66>; // n x 32 x i8 vector value
+def nxv1i8 : ValueType<8, 68>; // n x 1 x i8 vector value
+def nxv2i8 : ValueType<16, 69>; // n x 2 x i8 vector value
+def nxv4i8 : ValueType<32, 70>; // n x 4 x i8 vector value
+def nxv8i8 : ValueType<64, 71>; // n x 8 x i8 vector value
+def nxv16i8 : ValueType<128, 72>; // n x 16 x i8 vector value
+def nxv32i8 : ValueType<256, 73>; // n x 32 x i8 vector value
-def nxv1i16 : ValueType<16, 67>; // n x 1 x i16 vector value
-def nxv2i16 : ValueType<32, 68>; // n x 2 x i16 vector value
-def nxv4i16 : ValueType<64, 69>; // n x 4 x i16 vector value
-def nxv8i16 : ValueType<128, 70>; // n x 8 x i16 vector value
-def nxv16i16: ValueType<256, 71>; // n x 16 x i16 vector value
-def nxv32i16: ValueType<512, 72>; // n x 32 x i16 vector value
+def nxv1i16 : ValueType<16, 74>; // n x 1 x i16 vector value
+def nxv2i16 : ValueType<32, 75>; // n x 2 x i16 vector value
+def nxv4i16 : ValueType<64, 76>; // n x 4 x i16 vector value
+def nxv8i16 : ValueType<128, 77>; // n x 8 x i16 vector value
+def nxv16i16: ValueType<256, 78>; // n x 16 x i16 vector value
+def nxv32i16: ValueType<512, 79>; // n x 32 x i16 vector value
-def nxv1i32 : ValueType<32, 73>; // n x 1 x i32 vector value
-def nxv2i32 : ValueType<64, 74>; // n x 2 x i32 vector value
-def nxv4i32 : ValueType<128, 75>; // n x 4 x i32 vector value
-def nxv8i32 : ValueType<256, 76>; // n x 8 x i32 vector value
-def nxv16i32: ValueType<512, 77>; // n x 16 x i32 vector value
-def nxv32i32: ValueType<1024,78>; // n x 32 x i32 vector value
+def nxv1i32 : ValueType<32, 80>; // n x 1 x i32 vector value
+def nxv2i32 : ValueType<64, 81>; // n x 2 x i32 vector value
+def nxv4i32 : ValueType<128, 82>; // n x 4 x i32 vector value
+def nxv8i32 : ValueType<256, 83>; // n x 8 x i32 vector value
+def nxv16i32: ValueType<512, 84>; // n x 16 x i32 vector value
+def nxv32i32: ValueType<1024,85>; // n x 32 x i32 vector value
-def nxv1i64 : ValueType<64, 79>; // n x 1 x i64 vector value
-def nxv2i64 : ValueType<128, 80>; // n x 2 x i64 vector value
-def nxv4i64 : ValueType<256, 81>; // n x 4 x i64 vector value
-def nxv8i64 : ValueType<512, 82>; // n x 8 x i64 vector value
-def nxv16i64: ValueType<1024,83>; // n x 16 x i64 vector value
-def nxv32i64: ValueType<2048,84>; // n x 32 x i64 vector value
+def nxv1i64 : ValueType<64, 86>; // n x 1 x i64 vector value
+def nxv2i64 : ValueType<128, 87>; // n x 2 x i64 vector value
+def nxv4i64 : ValueType<256, 88>; // n x 4 x i64 vector value
+def nxv8i64 : ValueType<512, 89>; // n x 8 x i64 vector value
+def nxv16i64: ValueType<1024,90>; // n x 16 x i64 vector value
+def nxv32i64: ValueType<2048,91>; // n x 32 x i64 vector value
-def v2f16 : ValueType<32 , 85>; // 2 x f16 vector value
-def v4f16 : ValueType<64 , 86>; // 4 x f16 vector value
-def v8f16 : ValueType<128, 87>; // 8 x f16 vector value
-def v1f32 : ValueType<32 , 88>; // 1 x f32 vector value
-def v2f32 : ValueType<64 , 89>; // 2 x f32 vector value
-def v4f32 : ValueType<128, 90>; // 4 x f32 vector value
-def v8f32 : ValueType<256, 91>; // 8 x f32 vector value
-def v16f32 : ValueType<512, 92>; // 16 x f32 vector value
-def v1f64 : ValueType<64, 93>; // 1 x f64 vector value
-def v2f64 : ValueType<128, 94>; // 2 x f64 vector value
-def v4f64 : ValueType<256, 95>; // 4 x f64 vector value
-def v8f64 : ValueType<512, 96>; // 8 x f64 vector value
+def v2f16 : ValueType<32 , 92>; // 2 x f16 vector value
+def v4f16 : ValueType<64 , 93>; // 4 x f16 vector value
+def v8f16 : ValueType<128, 94>; // 8 x f16 vector value
+def v1f32 : ValueType<32 , 95>; // 1 x f32 vector value
+def v2f32 : ValueType<64 , 96>; // 2 x f32 vector value
+def v3f32 : ValueType<96 , 97>; // 3 x f32 vector value
+def v4f32 : ValueType<128, 98>; // 4 x f32 vector value
+def v5f32 : ValueType<160, 99>; // 5 x f32 vector value
+def v8f32 : ValueType<256, 100>; // 8 x f32 vector value
+def v16f32 : ValueType<512, 101>; // 16 x f32 vector value
+def v32f32 : ValueType<1024, 102>; // 32 x f32 vector value
+def v64f32 : ValueType<2048, 103>; // 64 x f32 vector value
+def v128f32 : ValueType<4096, 104>; // 128 x f32 vector value
+def v256f32 : ValueType<8182, 105>; // 256 x f32 vector value
+def v512f32 : ValueType<16384, 106>; // 512 x f32 vector value
+def v1024f32 : ValueType<32768, 107>; // 1024 x f32 vector value
+def v2048f32 : ValueType<65536, 108>; // 2048 x f32 vector value
+def v1f64 : ValueType<64, 109>; // 1 x f64 vector value
+def v2f64 : ValueType<128, 110>; // 2 x f64 vector value
+def v4f64 : ValueType<256, 111>; // 4 x f64 vector value
+def v8f64 : ValueType<512, 112>; // 8 x f64 vector value
-def nxv2f16 : ValueType<32 , 97>; // n x 2 x f16 vector value
-def nxv4f16 : ValueType<64 , 98>; // n x 4 x f16 vector value
-def nxv8f16 : ValueType<128, 99>; // n x 8 x f16 vector value
-def nxv1f32 : ValueType<32 , 100>; // n x 1 x f32 vector value
-def nxv2f32 : ValueType<64 , 101>; // n x 2 x f32 vector value
-def nxv4f32 : ValueType<128, 102>; // n x 4 x f32 vector value
-def nxv8f32 : ValueType<256, 103>; // n x 8 x f32 vector value
-def nxv16f32 : ValueType<512, 104>; // n x 16 x f32 vector value
-def nxv1f64 : ValueType<64, 105>; // n x 1 x f64 vector value
-def nxv2f64 : ValueType<128, 106>; // n x 2 x f64 vector value
-def nxv4f64 : ValueType<256, 107>; // n x 4 x f64 vector value
-def nxv8f64 : ValueType<512, 108>; // n x 8 x f64 vector value
+def nxv2f16 : ValueType<32 , 113>; // n x 2 x f16 vector value
+def nxv4f16 : ValueType<64 , 114>; // n x 4 x f16 vector value
+def nxv8f16 : ValueType<128, 115>; // n x 8 x f16 vector value
+def nxv1f32 : ValueType<32 , 116>; // n x 1 x f32 vector value
+def nxv2f32 : ValueType<64 , 117>; // n x 2 x f32 vector value
+def nxv4f32 : ValueType<128, 118>; // n x 4 x f32 vector value
+def nxv8f32 : ValueType<256, 119>; // n x 8 x f32 vector value
+def nxv16f32 : ValueType<512, 120>; // n x 16 x f32 vector value
+def nxv1f64 : ValueType<64, 121>; // n x 1 x f64 vector value
+def nxv2f64 : ValueType<128, 122>; // n x 2 x f64 vector value
+def nxv4f64 : ValueType<256, 123>; // n x 4 x f64 vector value
+def nxv8f64 : ValueType<512, 124>; // n x 8 x f64 vector value
-def x86mmx : ValueType<64 , 109>; // X86 MMX value
-def FlagVT : ValueType<0 , 110>; // Pre-RA sched glue
-def isVoid : ValueType<0 , 111>; // Produces no value
-def untyped: ValueType<8 , 112>; // Produces an untyped value
-def ExceptRef: ValueType<0, 113>; // WebAssembly's except_ref type
+def x86mmx : ValueType<64 , 125>; // X86 MMX value
+def FlagVT : ValueType<0 , 126>; // Pre-RA sched glue
+def isVoid : ValueType<0 , 127>; // Produces no value
+def untyped: ValueType<8 , 128>; // Produces an untyped value
+def exnref: ValueType<0, 129>; // WebAssembly's exnref type
def token : ValueType<0 , 248>; // TokenTy
def MetadataVT: ValueType<0, 249>; // Metadata
@@ -167,3 +182,14 @@ def iPTR : ValueType<0 , 254>;
// Pseudo valuetype to represent "any type of any size".
def Any : ValueType<0 , 255>;
+
+/// This class is for targets that want to use pointer types in patterns
+/// with the GlobalISelEmitter. Targets must define their own pointer
+/// derived from this class. The scalar argument should be an
+/// integer type with the same bit size as the ponter.
+/// e.g. def p0 : PtrValueType <i64, 0>;
+
+class PtrValueType <ValueType scalar, int addrspace> :
+ ValueType<scalar.Size, scalar.Value> {
+ int AddrSpace = addrspace;
+}
diff --git a/include/llvm/CodeGen/VirtRegMap.h b/include/llvm/CodeGen/VirtRegMap.h
index 6a8e50a7e5f5..70eb048f05eb 100644
--- a/include/llvm/CodeGen/VirtRegMap.h
+++ b/include/llvm/CodeGen/VirtRegMap.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/VirtRegMap.h - Virtual Register Map ---------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -68,8 +67,10 @@ class TargetInstrInfo;
public:
static char ID;
- VirtRegMap() : MachineFunctionPass(ID), Virt2PhysMap(NO_PHYS_REG),
- Virt2StackSlotMap(NO_STACK_SLOT), Virt2SplitMap(0) {}
+ VirtRegMap()
+ : MachineFunctionPass(ID), MRI(nullptr), TII(nullptr), TRI(nullptr),
+ MF(nullptr), Virt2PhysMap(NO_PHYS_REG),
+ Virt2StackSlotMap(NO_STACK_SLOT), Virt2SplitMap(0) {}
VirtRegMap(const VirtRegMap &) = delete;
VirtRegMap &operator=(const VirtRegMap &) = delete;
@@ -98,8 +99,8 @@ class TargetInstrInfo;
/// returns the physical register mapped to the specified
/// virtual register
- unsigned getPhys(unsigned virtReg) const {
- assert(TargetRegisterInfo::isVirtualRegister(virtReg));
+ Register getPhys(Register virtReg) const {
+ assert(virtReg.isVirtual());
return Virt2PhysMap[virtReg];
}
diff --git a/include/llvm/CodeGen/WasmEHFuncInfo.h b/include/llvm/CodeGen/WasmEHFuncInfo.h
index 219fff988f6e..887a1467b3e4 100644
--- a/include/llvm/CodeGen/WasmEHFuncInfo.h
+++ b/include/llvm/CodeGen/WasmEHFuncInfo.h
@@ -1,9 +1,8 @@
//===--- llvm/CodeGen/WasmEHFuncInfo.h --------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -29,10 +28,6 @@ struct WasmEHFuncInfo {
// When there is an entry <A, B>, if an exception is not caught by A, it
// should next unwind to the EH pad B.
DenseMap<BBOrMBB, BBOrMBB> EHPadUnwindMap;
- // For entry <A, B>, A is a BB with an instruction that may throw
- // (invoke/cleanupret in LLVM IR, call/rethrow in the backend) and B is an EH
- // pad that A unwinds to.
- DenseMap<BBOrMBB, BBOrMBB> ThrowUnwindMap;
// Helper functions
const BasicBlock *getEHPadUnwindDest(const BasicBlock *BB) const {
@@ -41,18 +36,9 @@ struct WasmEHFuncInfo {
void setEHPadUnwindDest(const BasicBlock *BB, const BasicBlock *Dest) {
EHPadUnwindMap[BB] = Dest;
}
- const BasicBlock *getThrowUnwindDest(BasicBlock *BB) const {
- return ThrowUnwindMap.lookup(BB).get<const BasicBlock *>();
- }
- void setThrowUnwindDest(const BasicBlock *BB, const BasicBlock *Dest) {
- ThrowUnwindMap[BB] = Dest;
- }
bool hasEHPadUnwindDest(const BasicBlock *BB) const {
return EHPadUnwindMap.count(BB);
}
- bool hasThrowUnwindDest(const BasicBlock *BB) const {
- return ThrowUnwindMap.count(BB);
- }
MachineBasicBlock *getEHPadUnwindDest(MachineBasicBlock *MBB) const {
return EHPadUnwindMap.lookup(MBB).get<MachineBasicBlock *>();
@@ -60,18 +46,9 @@ struct WasmEHFuncInfo {
void setEHPadUnwindDest(MachineBasicBlock *MBB, MachineBasicBlock *Dest) {
EHPadUnwindMap[MBB] = Dest;
}
- MachineBasicBlock *getThrowUnwindDest(MachineBasicBlock *MBB) const {
- return ThrowUnwindMap.lookup(MBB).get<MachineBasicBlock *>();
- }
- void setThrowUnwindDest(MachineBasicBlock *MBB, MachineBasicBlock *Dest) {
- ThrowUnwindMap[MBB] = Dest;
- }
bool hasEHPadUnwindDest(MachineBasicBlock *MBB) const {
return EHPadUnwindMap.count(MBB);
}
- bool hasThrowUnwindDest(MachineBasicBlock *MBB) const {
- return ThrowUnwindMap.count(MBB);
- }
};
// Analyze the IR in the given function to build WasmEHFuncInfo.
diff --git a/include/llvm/CodeGen/WinEHFuncInfo.h b/include/llvm/CodeGen/WinEHFuncInfo.h
index 8043024626a0..f098316de793 100644
--- a/include/llvm/CodeGen/WinEHFuncInfo.h
+++ b/include/llvm/CodeGen/WinEHFuncInfo.h
@@ -1,9 +1,8 @@
//===- llvm/CodeGen/WinEHFuncInfo.h -----------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//