Update prebuilt Clang to match Android kernel.
Bug: 132428451
Change-Id: I8f6e2cb23f381fc0c02ddea99b867e58e925e5be
diff --git a/linux-x64/clang/include/llvm/CodeGen/AccelTable.h b/linux-x64/clang/include/llvm/CodeGen/AccelTable.h
index 1392858..9731abd 100644
--- a/linux-x64/clang/include/llvm/CodeGen/AccelTable.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/Analysis.h b/linux-x64/clang/include/llvm/CodeGen/Analysis.h
index d77aee6..468768d 100644
--- a/linux-x64/clang/include/llvm/CodeGen/Analysis.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/AsmPrinter.h b/linux-x64/clang/include/llvm/CodeGen/AsmPrinter.h
index 14bc081..fb12bb2 100644
--- a/linux-x64/clang/include/llvm/CodeGen/AsmPrinter.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -71,6 +70,7 @@
class MDNode;
class Module;
class raw_ostream;
+class StackMaps;
class TargetLoweringObjectFile;
class TargetMachine;
@@ -121,9 +121,6 @@
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;
@@ -137,6 +134,9 @@
static char ID;
+protected:
+ /// Protected struct HandlerInfo and Handlers permit target extended
+ /// AsmPrinter adds their own handlers.
struct HandlerInfo {
AsmPrinterHandler *Handler;
const char *TimerName;
@@ -223,6 +223,9 @@
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;
@@ -365,6 +368,9 @@
/// emit the proxies we previously omitted in EmitGlobalVariable.
void emitGlobalGOTEquivs();
+ /// Emit the stack maps.
+ void emitStackMaps(StackMaps &SM);
+
//===------------------------------------------------------------------===//
// Overridable Hooks
//===------------------------------------------------------------------===//
@@ -542,7 +548,7 @@
///
/// \p Value - The value to emit.
/// \p Size - The size of the integer (in bytes) to emit.
- virtual void EmitDebugThreadLocal(const MCExpr *Value, unsigned Size) const;
+ virtual void EmitDebugValue(const MCExpr *Value, unsigned Size) const;
//===------------------------------------------------------------------===//
// Dwarf Lowering Routines
@@ -652,6 +658,8 @@
void EmitLLVMUsedList(const ConstantArray *InitList);
/// Emit llvm.ident metadata in an '.ident' directive.
void EmitModuleIdents(Module &M);
+ /// Emit bytes for llvm.commandline metadata.
+ void EmitModuleCommandLines(Module &M);
void EmitXXStructorList(const DataLayout &DL, const Constant *List,
bool isCtor);
diff --git a/linux-x64/clang/include/llvm/CodeGen/AsmPrinterHandler.h b/linux-x64/clang/include/llvm/CodeGen/AsmPrinterHandler.h
new file mode 100644
index 0000000..affb558
--- /dev/null
+++ b/linux-x64/clang/include/llvm/CodeGen/AsmPrinterHandler.h
@@ -0,0 +1,73 @@
+//===-- llvm/CodeGen/AsmPrinterHandler.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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a generic interface for AsmPrinter handlers,
+// like debug and EH info emitters.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_ASMPRINTERHANDLER_H
+#define LLVM_CODEGEN_ASMPRINTERHANDLER_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class AsmPrinter;
+class MachineBasicBlock;
+class MachineFunction;
+class MachineInstr;
+class MCSymbol;
+
+typedef MCSymbol *ExceptionSymbolProvider(AsmPrinter *Asm);
+
+/// Collects and handles AsmPrinter objects required to build debug
+/// or EH information.
+class AsmPrinterHandler {
+public:
+ virtual ~AsmPrinterHandler();
+
+ /// For symbols that have a size designated (e.g. common symbols),
+ /// this tracks that size.
+ virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) = 0;
+
+ /// Emit all sections that should come after the content.
+ virtual void endModule() = 0;
+
+ /// Gather pre-function debug information.
+ /// Every beginFunction(MF) call should be followed by an endFunction(MF)
+ /// call.
+ virtual void beginFunction(const MachineFunction *MF) = 0;
+
+ // Emit any of function marker (like .cfi_endproc). This is called
+ // before endFunction and cannot switch sections.
+ virtual void markFunctionEnd();
+
+ /// Gather post-function debug information.
+ /// Please note that some AsmPrinter implementations may not call
+ /// beginFunction at all.
+ virtual void endFunction(const MachineFunction *MF) = 0;
+
+ virtual void beginFragment(const MachineBasicBlock *MBB,
+ ExceptionSymbolProvider ESP) {}
+ virtual void endFragment() {}
+
+ /// Emit target-specific EH funclet machinery.
+ virtual void beginFunclet(const MachineBasicBlock &MBB,
+ MCSymbol *Sym = nullptr) {}
+ virtual void endFunclet() {}
+
+ /// Process beginning of an instruction.
+ virtual void beginInstruction(const MachineInstr *MI) = 0;
+
+ /// Process end of an instruction.
+ virtual void endInstruction() = 0;
+};
+} // End of namespace llvm
+
+#endif
diff --git a/linux-x64/clang/include/llvm/CodeGen/AtomicExpandUtils.h b/linux-x64/clang/include/llvm/CodeGen/AtomicExpandUtils.h
index b1adf66..8a46c6e 100644
--- a/linux-x64/clang/include/llvm/CodeGen/AtomicExpandUtils.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/BasicTTIImpl.h b/linux-x64/clang/include/llvm/CodeGen/BasicTTIImpl.h
index b460cdc..1e9aeab 100644
--- a/linux-x64/clang/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -80,6 +79,23 @@
using BaseT = TargetTransformInfoImplCRTPBase<T>;
using TTI = TargetTransformInfo;
+ /// Estimate a cost of Broadcast as an extract and sequence of insert
+ /// operations.
+ unsigned getBroadcastShuffleOverhead(Type *Ty) {
+ assert(Ty->isVectorTy() && "Can only shuffle vectors");
+ unsigned Cost = 0;
+ // Broadcast cost is equal to the cost of extracting the zero'th element
+ // plus the cost of inserting it into every element of the result vector.
+ Cost += static_cast<T *>(this)->getVectorInstrCost(
+ Instruction::ExtractElement, Ty, 0);
+
+ for (int i = 0, e = Ty->getVectorNumElements(); i < e; ++i) {
+ Cost += static_cast<T *>(this)->getVectorInstrCost(
+ Instruction::InsertElement, Ty, i);
+ }
+ return Cost;
+ }
+
/// Estimate a cost of shuffle as a sequence of extract and insert
/// operations.
unsigned getPermuteShuffleOverhead(Type *Ty) {
@@ -101,6 +117,50 @@
return Cost;
}
+ /// Estimate a cost of subvector extraction as a sequence of extract and
+ /// insert operations.
+ unsigned getExtractSubvectorOverhead(Type *Ty, int Index, Type *SubTy) {
+ assert(Ty && Ty->isVectorTy() && SubTy && SubTy->isVectorTy() &&
+ "Can only extract subvectors from vectors");
+ int NumSubElts = SubTy->getVectorNumElements();
+ assert((Index + NumSubElts) <= (int)Ty->getVectorNumElements() &&
+ "SK_ExtractSubvector index out of range");
+
+ unsigned Cost = 0;
+ // Subvector extraction cost is equal to the cost of extracting element from
+ // the source type plus the cost of inserting them into the result vector
+ // type.
+ for (int i = 0; i != NumSubElts; ++i) {
+ Cost += static_cast<T *>(this)->getVectorInstrCost(
+ Instruction::ExtractElement, Ty, i + Index);
+ Cost += static_cast<T *>(this)->getVectorInstrCost(
+ Instruction::InsertElement, SubTy, i);
+ }
+ return Cost;
+ }
+
+ /// Estimate a cost of subvector insertion as a sequence of extract and
+ /// insert operations.
+ unsigned getInsertSubvectorOverhead(Type *Ty, int Index, Type *SubTy) {
+ assert(Ty && Ty->isVectorTy() && SubTy && SubTy->isVectorTy() &&
+ "Can only insert subvectors into vectors");
+ int NumSubElts = SubTy->getVectorNumElements();
+ assert((Index + NumSubElts) <= (int)Ty->getVectorNumElements() &&
+ "SK_InsertSubvector index out of range");
+
+ unsigned Cost = 0;
+ // Subvector insertion cost is equal to the cost of extracting element from
+ // the source type plus the cost of inserting them into the result vector
+ // type.
+ for (int i = 0; i != NumSubElts; ++i) {
+ Cost += static_cast<T *>(this)->getVectorInstrCost(
+ Instruction::ExtractElement, SubTy, i);
+ Cost += static_cast<T *>(this)->getVectorInstrCost(
+ Instruction::InsertElement, Ty, i + Index);
+ }
+ return Cost;
+ }
+
/// Local query method delegates up to T which *must* implement this!
const TargetSubtargetInfo *getST() const {
return static_cast<const T *>(this)->getST();
@@ -554,14 +614,20 @@
unsigned getShuffleCost(TTI::ShuffleKind Kind, Type *Tp, int Index,
Type *SubTp) {
switch (Kind) {
+ case TTI::SK_Broadcast:
+ return getBroadcastShuffleOverhead(Tp);
case TTI::SK_Select:
+ case TTI::SK_Reverse:
case TTI::SK_Transpose:
case TTI::SK_PermuteSingleSrc:
case TTI::SK_PermuteTwoSrc:
return getPermuteShuffleOverhead(Tp);
- default:
- return 1;
+ case TTI::SK_ExtractSubvector:
+ return getExtractSubvectorOverhead(Tp, Index, SubTp);
+ case TTI::SK_InsertSubvector:
+ return getInsertSubvectorOverhead(Tp, Index, SubTp);
}
+ llvm_unreachable("Unknown TTI::ShuffleKind");
}
unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
@@ -783,8 +849,9 @@
unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy,
unsigned Factor,
ArrayRef<unsigned> Indices,
- unsigned Alignment,
- unsigned AddressSpace) {
+ unsigned Alignment, unsigned AddressSpace,
+ bool UseMaskForCond = false,
+ bool UseMaskForGaps = false) {
VectorType *VT = dyn_cast<VectorType>(VecTy);
assert(VT && "Expect a vector type for interleaved memory op");
@@ -795,8 +862,13 @@
VectorType *SubVT = VectorType::get(VT->getElementType(), NumSubElts);
// Firstly, the cost of load/store operation.
- unsigned Cost = static_cast<T *>(this)->getMemoryOpCost(
- Opcode, VecTy, Alignment, AddressSpace);
+ unsigned Cost;
+ if (UseMaskForCond || UseMaskForGaps)
+ Cost = static_cast<T *>(this)->getMaskedMemoryOpCost(
+ Opcode, VecTy, Alignment, AddressSpace);
+ else
+ Cost = static_cast<T *>(this)->getMemoryOpCost(Opcode, VecTy, Alignment,
+ AddressSpace);
// Legalize the vector type, and get the legalized and unlegalized type
// sizes.
@@ -892,6 +964,40 @@
->getVectorInstrCost(Instruction::InsertElement, VT, i);
}
+ if (!UseMaskForCond)
+ return Cost;
+
+ Type *I8Type = Type::getInt8Ty(VT->getContext());
+ VectorType *MaskVT = VectorType::get(I8Type, NumElts);
+ SubVT = VectorType::get(I8Type, NumSubElts);
+
+ // The Mask shuffling cost is extract all the elements of the Mask
+ // and insert each of them Factor times into the wide vector:
+ //
+ // E.g. an interleaved group with factor 3:
+ // %mask = icmp ult <8 x i32> %vec1, %vec2
+ // %interleaved.mask = shufflevector <8 x i1> %mask, <8 x i1> undef,
+ // <24 x i32> <0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7>
+ // The cost is estimated as extract all mask elements from the <8xi1> mask
+ // vector and insert them factor times into the <24xi1> shuffled mask
+ // vector.
+ for (unsigned i = 0; i < NumSubElts; i++)
+ Cost += static_cast<T *>(this)->getVectorInstrCost(
+ Instruction::ExtractElement, SubVT, i);
+
+ for (unsigned i = 0; i < NumElts; i++)
+ Cost += static_cast<T *>(this)->getVectorInstrCost(
+ Instruction::InsertElement, MaskVT, i);
+
+ // The Gaps mask is invariant and created outside the loop, therefore the
+ // cost of creating it is not accounted for here. However if we have both
+ // a MaskForGaps and some other mask that guards the execution of the
+ // memory access, we need to account for the cost of And-ing the two masks
+ // inside the loop.
+ if (UseMaskForGaps)
+ Cost += static_cast<T *>(this)->getArithmeticInstrCost(
+ BinaryOperator::And, MaskVT);
+
return Cost;
}
@@ -901,6 +1007,7 @@
unsigned VF = 1) {
unsigned RetVF = (RetTy->isVectorTy() ? RetTy->getVectorNumElements() : 1);
assert((RetVF == 1 || VF == 1) && "VF > 1 and RetVF is a vector type");
+ auto *ConcreteTTI = static_cast<T *>(this);
switch (IID) {
default: {
@@ -926,29 +1033,24 @@
ScalarizationCost += getOperandsScalarizationOverhead(Args, VF);
}
- return static_cast<T *>(this)->
- getIntrinsicInstrCost(IID, RetTy, Types, FMF, ScalarizationCost);
+ return ConcreteTTI->getIntrinsicInstrCost(IID, RetTy, Types, FMF,
+ ScalarizationCost);
}
case Intrinsic::masked_scatter: {
assert(VF == 1 && "Can't vectorize types here.");
Value *Mask = Args[3];
bool VarMask = !isa<Constant>(Mask);
unsigned Alignment = cast<ConstantInt>(Args[2])->getZExtValue();
- return
- static_cast<T *>(this)->getGatherScatterOpCost(Instruction::Store,
- Args[0]->getType(),
- Args[1], VarMask,
- Alignment);
+ return ConcreteTTI->getGatherScatterOpCost(
+ Instruction::Store, Args[0]->getType(), Args[1], VarMask, Alignment);
}
case Intrinsic::masked_gather: {
assert(VF == 1 && "Can't vectorize types here.");
Value *Mask = Args[2];
bool VarMask = !isa<Constant>(Mask);
unsigned Alignment = cast<ConstantInt>(Args[1])->getZExtValue();
- return
- static_cast<T *>(this)->getGatherScatterOpCost(Instruction::Load,
- RetTy, Args[0], VarMask,
- Alignment);
+ return ConcreteTTI->getGatherScatterOpCost(Instruction::Load, RetTy,
+ Args[0], VarMask, Alignment);
}
case Intrinsic::experimental_vector_reduce_add:
case Intrinsic::experimental_vector_reduce_mul:
@@ -964,6 +1066,45 @@
case Intrinsic::experimental_vector_reduce_umax:
case Intrinsic::experimental_vector_reduce_umin:
return getIntrinsicInstrCost(IID, RetTy, Args[0]->getType(), FMF);
+ case Intrinsic::fshl:
+ case Intrinsic::fshr: {
+ Value *X = Args[0];
+ Value *Y = Args[1];
+ Value *Z = Args[2];
+ TTI::OperandValueProperties OpPropsX, OpPropsY, OpPropsZ, OpPropsBW;
+ TTI::OperandValueKind OpKindX = TTI::getOperandInfo(X, OpPropsX);
+ TTI::OperandValueKind OpKindY = TTI::getOperandInfo(Y, OpPropsY);
+ TTI::OperandValueKind OpKindZ = TTI::getOperandInfo(Z, OpPropsZ);
+ TTI::OperandValueKind OpKindBW = TTI::OK_UniformConstantValue;
+ OpPropsBW = isPowerOf2_32(RetTy->getScalarSizeInBits()) ? TTI::OP_PowerOf2
+ : TTI::OP_None;
+ // fshl: (X << (Z % BW)) | (Y >> (BW - (Z % BW)))
+ // fshr: (X << (BW - (Z % BW))) | (Y >> (Z % BW))
+ unsigned Cost = 0;
+ Cost += ConcreteTTI->getArithmeticInstrCost(BinaryOperator::Or, RetTy);
+ Cost += ConcreteTTI->getArithmeticInstrCost(BinaryOperator::Sub, RetTy);
+ Cost += ConcreteTTI->getArithmeticInstrCost(BinaryOperator::Shl, RetTy,
+ OpKindX, OpKindZ, OpPropsX);
+ Cost += ConcreteTTI->getArithmeticInstrCost(BinaryOperator::LShr, RetTy,
+ OpKindY, OpKindZ, OpPropsY);
+ // Non-constant shift amounts requires a modulo.
+ if (OpKindZ != TTI::OK_UniformConstantValue &&
+ OpKindZ != TTI::OK_NonUniformConstantValue)
+ Cost += ConcreteTTI->getArithmeticInstrCost(BinaryOperator::URem, RetTy,
+ OpKindZ, OpKindBW, OpPropsZ,
+ OpPropsBW);
+ // For non-rotates (X != Y) we must add shift-by-zero handling costs.
+ if (X != Y) {
+ Type *CondTy = Type::getInt1Ty(RetTy->getContext());
+ if (RetVF > 1)
+ CondTy = VectorType::get(CondTy, RetVF);
+ Cost += ConcreteTTI->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy,
+ CondTy, nullptr);
+ Cost += ConcreteTTI->getCmpSelInstrCost(BinaryOperator::Select, RetTy,
+ CondTy, nullptr);
+ }
+ return Cost;
+ }
}
}
@@ -974,6 +1115,9 @@
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) {
@@ -1002,8 +1146,8 @@
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;
}
@@ -1042,12 +1186,12 @@
case Intrinsic::minnum:
ISDs.push_back(ISD::FMINNUM);
if (FMF.noNaNs())
- ISDs.push_back(ISD::FMINNAN);
+ ISDs.push_back(ISD::FMINIMUM);
break;
case Intrinsic::maxnum:
ISDs.push_back(ISD::FMAXNUM);
if (FMF.noNaNs())
- ISDs.push_back(ISD::FMAXNAN);
+ ISDs.push_back(ISD::FMAXIMUM);
break;
case Intrinsic::copysign:
ISDs.push_back(ISD::FCOPYSIGN);
@@ -1085,44 +1229,123 @@
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);
+ return ConcreteTTI->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);
+ return ConcreteTTI->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::FMul, Tys[0],
+ /*IsPairwiseForm=*/false);
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);
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);
+ 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::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::ctpop:
ISDs.push_back(ISD::CTPOP);
// In case of legalization use TCC_Expensive. This is cheaper than a
@@ -1163,17 +1386,16 @@
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
@@ -1191,7 +1413,7 @@
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()) {
@@ -1284,24 +1506,36 @@
LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
while (NumVecElts > MVTLen) {
NumVecElts /= 2;
+ Type *SubTy = VectorType::get(ScalarTy, NumVecElts);
// Assume the pairwise shuffles add a cost.
ShuffleCost += (IsPairwise + 1) *
ConcreteTTI->getShuffleCost(TTI::SK_ExtractSubvector, Ty,
- NumVecElts, Ty);
- ArithCost += ConcreteTTI->getArithmeticInstrCost(Opcode, Ty);
- Ty = VectorType::get(ScalarTy, NumVecElts);
+ NumVecElts, SubTy);
+ ArithCost += ConcreteTTI->getArithmeticInstrCost(Opcode, SubTy);
+ Ty = SubTy;
++LongVectorCount;
}
+
+ NumReduxLevels -= LongVectorCount;
+
// The minimal length of the vector is limited by the real length of vector
// operations performed on the current platform. That's why several final
// reduction operations are performed on the vectors with the same
// architecture-dependent length.
- ShuffleCost += (NumReduxLevels - LongVectorCount) * (IsPairwise + 1) *
- ConcreteTTI->getShuffleCost(TTI::SK_ExtractSubvector, Ty,
- NumVecElts, Ty);
- ArithCost += (NumReduxLevels - LongVectorCount) *
+
+ // Non pairwise reductions need one shuffle per reduction level. Pairwise
+ // reductions need two shuffles on every level, but the last one. On that
+ // level one of the shuffles is <0, u, u, ...> which is identity.
+ unsigned NumShuffles = NumReduxLevels;
+ if (IsPairwise && NumReduxLevels >= 1)
+ NumShuffles += NumReduxLevels - 1;
+ ShuffleCost += NumShuffles *
+ ConcreteTTI->getShuffleCost(TTI::SK_PermuteSingleSrc, Ty,
+ 0, Ty);
+ ArithCost += NumReduxLevels *
ConcreteTTI->getArithmeticInstrCost(Opcode, Ty);
- return ShuffleCost + ArithCost + getScalarizationOverhead(Ty, false, true);
+ return ShuffleCost + ArithCost +
+ ConcreteTTI->getVectorInstrCost(Instruction::ExtractElement, Ty, 0);
}
/// Try to calculate op costs for min/max reduction operations.
@@ -1331,37 +1565,46 @@
LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
while (NumVecElts > MVTLen) {
NumVecElts /= 2;
+ Type *SubTy = VectorType::get(ScalarTy, NumVecElts);
+ CondTy = VectorType::get(ScalarCondTy, NumVecElts);
+
// Assume the pairwise shuffles add a cost.
ShuffleCost += (IsPairwise + 1) *
ConcreteTTI->getShuffleCost(TTI::SK_ExtractSubvector, Ty,
- NumVecElts, Ty);
+ NumVecElts, SubTy);
MinMaxCost +=
- ConcreteTTI->getCmpSelInstrCost(CmpOpcode, Ty, CondTy, nullptr) +
- ConcreteTTI->getCmpSelInstrCost(Instruction::Select, Ty, CondTy,
+ ConcreteTTI->getCmpSelInstrCost(CmpOpcode, SubTy, CondTy, nullptr) +
+ ConcreteTTI->getCmpSelInstrCost(Instruction::Select, SubTy, CondTy,
nullptr);
- Ty = VectorType::get(ScalarTy, NumVecElts);
- CondTy = VectorType::get(ScalarCondTy, NumVecElts);
+ Ty = SubTy;
++LongVectorCount;
}
+
+ NumReduxLevels -= LongVectorCount;
+
// The minimal length of the vector is limited by the real length of vector
// operations performed on the current platform. That's why several final
// reduction opertions are perfomed on the vectors with the same
// architecture-dependent length.
- ShuffleCost += (NumReduxLevels - LongVectorCount) * (IsPairwise + 1) *
- ConcreteTTI->getShuffleCost(TTI::SK_ExtractSubvector, Ty,
- NumVecElts, Ty);
+
+ // Non pairwise reductions need one shuffle per reduction level. Pairwise
+ // reductions need two shuffles on every level, but the last one. On that
+ // level one of the shuffles is <0, u, u, ...> which is identity.
+ unsigned NumShuffles = NumReduxLevels;
+ if (IsPairwise && NumReduxLevels >= 1)
+ NumShuffles += NumReduxLevels - 1;
+ ShuffleCost += NumShuffles *
+ ConcreteTTI->getShuffleCost(TTI::SK_PermuteSingleSrc, Ty,
+ 0, Ty);
MinMaxCost +=
- (NumReduxLevels - LongVectorCount) *
+ NumReduxLevels *
(ConcreteTTI->getCmpSelInstrCost(CmpOpcode, Ty, CondTy, nullptr) +
ConcreteTTI->getCmpSelInstrCost(Instruction::Select, Ty, CondTy,
nullptr));
- // Need 3 extractelement instructions for scalarization + an additional
- // scalar select instruction.
+ // The last min/max should be in vector registers and we counted it above.
+ // So just need a single extractelement.
return ShuffleCost + MinMaxCost +
- 3 * getScalarizationOverhead(Ty, /*Insert=*/false,
- /*Extract=*/true) +
- ConcreteTTI->getCmpSelInstrCost(Instruction::Select, ScalarTy,
- ScalarCondTy, nullptr);
+ ConcreteTTI->getVectorInstrCost(Instruction::ExtractElement, Ty, 0);
}
unsigned getVectorSplitCost() { return 1; }
diff --git a/linux-x64/clang/include/llvm/CodeGen/BuiltinGCs.h b/linux-x64/clang/include/llvm/CodeGen/BuiltinGCs.h
new file mode 100644
index 0000000..d44183d
--- /dev/null
+++ b/linux-x64/clang/include/llvm/CodeGen/BuiltinGCs.h
@@ -0,0 +1,32 @@
+//===-- BuiltinGCs.h - Garbage collector linkage hacks --------------------===//
+//
+// 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 hack functions to force linking in the builtin GC
+// components.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_GCS_H
+#define LLVM_CODEGEN_GCS_H
+
+namespace llvm {
+
+/// FIXME: Collector instances are not useful on their own. These no longer
+/// serve any purpose except to link in the plugins.
+
+/// Ensure the definition of the builtin GCs gets linked in
+void linkAllBuiltinGCs();
+
+/// Creates an ocaml-compatible metadata printer.
+void linkOcamlGCPrinter();
+
+/// Creates an erlang-compatible metadata printer.
+void linkErlangGCPrinter();
+}
+
+#endif
diff --git a/linux-x64/clang/include/llvm/CodeGen/CalcSpillWeights.h b/linux-x64/clang/include/llvm/CodeGen/CalcSpillWeights.h
index f85767f..9b8b732 100644
--- a/linux-x64/clang/include/llvm/CodeGen/CalcSpillWeights.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/CallingConvLower.h b/linux-x64/clang/include/llvm/CodeGen/CallingConvLower.h
index efcf80b..78aebbe 100644
--- a/linux-x64/clang/include/llvm/CodeGen/CallingConvLower.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/CommandFlags.inc b/linux-x64/clang/include/llvm/CodeGen/CommandFlags.inc
index 6535e06..5b9564c 100644
--- a/linux-x64/clang/include/llvm/CodeGen/CommandFlags.inc
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -114,10 +113,16 @@
clEnumValN(TargetMachine::CGFT_Null, "null",
"Emit nothing, for performance testing")));
-static cl::opt<bool>
- DisableFPElim("disable-fp-elim",
- cl::desc("Disable frame pointer elimination optimization"),
- cl::init(false));
+static cl::opt<llvm::FramePointer::FP> FramePointerUsage(
+ "frame-pointer", cl::desc("Specify frame pointer elimination optimization"),
+ cl::init(llvm::FramePointer::None),
+ cl::values(
+ clEnumValN(llvm::FramePointer::All, "all",
+ "Disable frame pointer elimination"),
+ clEnumValN(llvm::FramePointer::NonLeaf, "non-leaf",
+ "Disable frame pointer elimination for non-leaf frame"),
+ clEnumValN(llvm::FramePointer::None, "none",
+ "Enable frame pointer elimination")));
static cl::opt<bool> EnableUnsafeFPMath(
"enable-unsafe-fp-math",
@@ -368,9 +373,14 @@
NewAttrs.addAttribute("target-cpu", CPU);
if (!Features.empty())
NewAttrs.addAttribute("target-features", Features);
- if (DisableFPElim.getNumOccurrences() > 0)
- NewAttrs.addAttribute("no-frame-pointer-elim",
- DisableFPElim ? "true" : "false");
+ if (FramePointerUsage.getNumOccurrences() > 0) {
+ if (FramePointerUsage == llvm::FramePointer::All)
+ NewAttrs.addAttribute("frame-pointer", "all");
+ else if (FramePointerUsage == llvm::FramePointer::NonLeaf)
+ NewAttrs.addAttribute("frame-pointer", "non-leaf");
+ else if (FramePointerUsage == llvm::FramePointer::None)
+ NewAttrs.addAttribute("frame-pointer", "none");
+ }
if (DisableTailCalls.getNumOccurrences() > 0)
NewAttrs.addAttribute("disable-tail-calls",
toStringRef(DisableTailCalls));
diff --git a/linux-x64/clang/include/llvm/CodeGen/CostTable.h b/linux-x64/clang/include/llvm/CodeGen/CostTable.h
index 48ad769..52f3bfa 100644
--- a/linux-x64/clang/include/llvm/CodeGen/CostTable.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/DAGCombine.h b/linux-x64/clang/include/llvm/CodeGen/DAGCombine.h
index 8b59190..9441873 100644
--- a/linux-x64/clang/include/llvm/CodeGen/DAGCombine.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/DFAPacketizer.h b/linux-x64/clang/include/llvm/CodeGen/DFAPacketizer.h
index d3aabe2..cf58ee0 100644
--- a/linux-x64/clang/include/llvm/CodeGen/DFAPacketizer.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/DIE.h b/linux-x64/clang/include/llvm/CodeGen/DIE.h
index 7d486b1..9e7167f 100644
--- a/linux-x64/clang/include/llvm/CodeGen/DIE.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -800,7 +799,7 @@
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/linux-x64/clang/include/llvm/CodeGen/DIEValue.def b/linux-x64/clang/include/llvm/CodeGen/DIEValue.def
index a3fce9b..c6c4c9a 100644
--- a/linux-x64/clang/include/llvm/CodeGen/DIEValue.def
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/DbgEntityHistoryCalculator.h b/linux-x64/clang/include/llvm/CodeGen/DbgEntityHistoryCalculator.h
new file mode 100644
index 0000000..b5374d8
--- /dev/null
+++ b/linux-x64/clang/include/llvm/CodeGen/DbgEntityHistoryCalculator.h
@@ -0,0 +1,86 @@
+//===- llvm/CodeGen/DbgEntityHistoryCalculator.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_DBGVALUEHISTORYCALCULATOR_H
+#define LLVM_CODEGEN_DBGVALUEHISTORYCALCULATOR_H
+
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include <utility>
+
+namespace llvm {
+
+class DILocalVariable;
+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.
+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>;
+ using InlinedEntity = std::pair<const DINode *, const DILocation *>;
+ using InstrRangesMap = MapVector<InlinedEntity, InstrRanges>;
+
+private:
+ InstrRangesMap VarInstrRanges;
+
+public:
+ void startInstrRange(InlinedEntity Var, const MachineInstr &MI);
+ void endInstrRange(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;
+
+ 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(); }
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ LLVM_DUMP_METHOD void dump() const;
+#endif
+};
+
+/// For each inlined instance of a source-level label, keep the corresponding
+/// DBG_LABEL instruction. The DBG_LABEL instruction could be used to generate
+/// a temporary (assembler) label before it.
+class DbgLabelInstrMap {
+public:
+ using InlinedEntity = std::pair<const DINode *, const DILocation *>;
+ using InstrMap = MapVector<InlinedEntity, const MachineInstr *>;
+
+private:
+ InstrMap LabelInstr;
+
+public:
+ void addInstr(InlinedEntity Label, const MachineInstr &MI);
+
+ bool empty() const { return LabelInstr.empty(); }
+ void clear() { LabelInstr.clear(); }
+ InstrMap::const_iterator begin() const { return LabelInstr.begin(); }
+ InstrMap::const_iterator end() const { return LabelInstr.end(); }
+};
+
+void calculateDbgEntityHistory(const MachineFunction *MF,
+ const TargetRegisterInfo *TRI,
+ DbgValueHistoryMap &DbgValues,
+ DbgLabelInstrMap &DbgLabels);
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_DBGVALUEHISTORYCALCULATOR_H
diff --git a/linux-x64/clang/include/llvm/CodeGen/DebugHandlerBase.h b/linux-x64/clang/include/llvm/CodeGen/DebugHandlerBase.h
new file mode 100644
index 0000000..3771d48
--- /dev/null
+++ b/linux-x64/clang/include/llvm/CodeGen/DebugHandlerBase.h
@@ -0,0 +1,137 @@
+//===-- llvm/CodeGen/DebugHandlerBase.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Common functionality for different debug information format backends.
+// LLVM currently supports DWARF and CodeView.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_DEBUGHANDLERBASE_H
+#define LLVM_CODEGEN_DEBUGHANDLERBASE_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/CodeGen/AsmPrinterHandler.h"
+#include "llvm/CodeGen/DbgEntityHistoryCalculator.h"
+#include "llvm/CodeGen/LexicalScopes.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+
+namespace llvm {
+
+class AsmPrinter;
+class MachineInstr;
+class MachineModuleInfo;
+
+/// Represents the location at which a variable is stored.
+struct DbgVariableLocation {
+ /// Base register.
+ unsigned Register;
+
+ /// Chain of offsetted loads necessary to load the value if it lives in
+ /// memory. Every load except for the last is pointer-sized.
+ SmallVector<int64_t, 1> LoadChain;
+
+ /// Present if the location is part of a larger variable.
+ llvm::Optional<llvm::DIExpression::FragmentInfo> FragmentInfo;
+
+ /// Extract a VariableLocation from a MachineInstr.
+ /// This will only work if Instruction is a debug value instruction
+ /// and the associated DIExpression is in one of the supported forms.
+ /// If these requirements are not met, the returned Optional will not
+ /// have a value.
+ static Optional<DbgVariableLocation>
+ extractFromMachineInstruction(const MachineInstr &Instruction);
+};
+
+/// Base class for debug information backends. Common functionality related to
+/// tracking which variables and scopes are alive at a given PC live here.
+class DebugHandlerBase : public AsmPrinterHandler {
+protected:
+ DebugHandlerBase(AsmPrinter *A);
+
+ /// Target of debug info emission.
+ AsmPrinter *Asm;
+
+ /// Collected machine module information.
+ MachineModuleInfo *MMI;
+
+ /// Previous instruction's location information. This is used to
+ /// determine label location to indicate scope boundaries in debug info.
+ /// We track the previous instruction's source location (if not line 0),
+ /// whether it was a label, and its parent BB.
+ DebugLoc PrevInstLoc;
+ MCSymbol *PrevLabel = nullptr;
+ const MachineBasicBlock *PrevInstBB = nullptr;
+
+ /// This location indicates end of function prologue and beginning of
+ /// function body.
+ DebugLoc PrologEndLoc;
+
+ /// If nonnull, stores the current machine instruction we're processing.
+ const MachineInstr *CurMI = nullptr;
+
+ LexicalScopes LScopes;
+
+ /// History of DBG_VALUE and clobber instructions for each user
+ /// variable. Variables are listed in order of appearance.
+ DbgValueHistoryMap DbgValues;
+
+ /// Mapping of inlined labels and DBG_LABEL machine instruction.
+ DbgLabelInstrMap DbgLabels;
+
+ /// Maps instruction with label emitted before instruction.
+ /// FIXME: Make this private from DwarfDebug, we have the necessary accessors
+ /// for it.
+ DenseMap<const MachineInstr *, MCSymbol *> LabelsBeforeInsn;
+
+ /// Maps instruction with label emitted after instruction.
+ DenseMap<const MachineInstr *, MCSymbol *> LabelsAfterInsn;
+
+ /// Indentify instructions that are marking the beginning of or
+ /// ending of a scope.
+ void identifyScopeMarkers();
+
+ /// Ensure that a label will be emitted before MI.
+ void requestLabelBeforeInsn(const MachineInstr *MI) {
+ LabelsBeforeInsn.insert(std::make_pair(MI, nullptr));
+ }
+
+ /// Ensure that a label will be emitted after MI.
+ void requestLabelAfterInsn(const MachineInstr *MI) {
+ LabelsAfterInsn.insert(std::make_pair(MI, nullptr));
+ }
+
+ virtual void beginFunctionImpl(const MachineFunction *MF) = 0;
+ virtual void endFunctionImpl(const MachineFunction *MF) = 0;
+ virtual void skippedNonDebugFunction() {}
+
+ // AsmPrinterHandler overrides.
+public:
+ void beginInstruction(const MachineInstr *MI) override;
+ void endInstruction() override;
+
+ void beginFunction(const MachineFunction *MF) override;
+ void endFunction(const MachineFunction *MF) override;
+
+ /// Return Label preceding the instruction.
+ MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
+
+ /// Return Label immediately following the instruction.
+ MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
+
+ /// Return the function-local offset of an instruction. A label for the
+ /// instruction \p MI should exist (\ref getLabelAfterInsn).
+ 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);
+};
+
+}
+
+#endif
diff --git a/linux-x64/clang/include/llvm/CodeGen/DwarfStringPoolEntry.h b/linux-x64/clang/include/llvm/CodeGen/DwarfStringPoolEntry.h
index 8b1a7af..e189352 100644
--- a/linux-x64/clang/include/llvm/CodeGen/DwarfStringPoolEntry.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/EdgeBundles.h b/linux-x64/clang/include/llvm/CodeGen/EdgeBundles.h
index c31fad2..28cdf54 100644
--- a/linux-x64/clang/include/llvm/CodeGen/EdgeBundles.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/ExecutionDomainFix.h b/linux-x64/clang/include/llvm/CodeGen/ExecutionDomainFix.h
index 338c214..6836678 100644
--- a/linux-x64/clang/include/llvm/CodeGen/ExecutionDomainFix.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/ExpandReductions.h b/linux-x64/clang/include/llvm/CodeGen/ExpandReductions.h
index c6aaaad..5dbed07 100644
--- a/linux-x64/clang/include/llvm/CodeGen/ExpandReductions.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/FastISel.h b/linux-x64/clang/include/llvm/CodeGen/FastISel.h
index 865d8a8..394324b 100644
--- a/linux-x64/clang/include/llvm/CodeGen/FastISel.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
///
diff --git a/linux-x64/clang/include/llvm/CodeGen/FaultMaps.h b/linux-x64/clang/include/llvm/CodeGen/FaultMaps.h
index 55e25c9..a1e2349 100644
--- a/linux-x64/clang/include/llvm/CodeGen/FaultMaps.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/FunctionLoweringInfo.h b/linux-x64/clang/include/llvm/CodeGen/FunctionLoweringInfo.h
index 5fe4f89..f5f37d1 100644
--- a/linux-x64/clang/include/llvm/CodeGen/FunctionLoweringInfo.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -16,6 +15,7 @@
#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"
@@ -175,6 +175,10 @@
/// 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;
@@ -246,6 +250,7 @@
return 0;
unsigned &R = ValueMap[V];
assert(R == 0 && "Already initialized this value register!");
+ assert(VirtReg2Value.empty());
return R = CreateRegs(V->getType());
}
diff --git a/linux-x64/clang/include/llvm/CodeGen/GCMetadata.h b/linux-x64/clang/include/llvm/CodeGen/GCMetadata.h
index ad2599f..77cd356 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GCMetadata.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -55,12 +54,11 @@
/// GCPoint - Metadata for a collector-safe point in machine code.
///
struct GCPoint {
- GC::PointKind Kind; ///< The kind of the safe point.
MCSymbol *Label; ///< A label.
DebugLoc Loc;
- GCPoint(GC::PointKind K, MCSymbol *L, DebugLoc DL)
- : Kind(K), Label(L), Loc(std::move(DL)) {}
+ GCPoint(MCSymbol *L, DebugLoc DL)
+ : Label(L), Loc(std::move(DL)) {}
};
/// GCRoot - Metadata for a pointer to an object managed by the garbage
@@ -124,8 +122,8 @@
/// addSafePoint - Notes the existence of a safe point. Num is the ID of the
/// label just prior to the safe point (if the code generator is using
/// MachineModuleInfo).
- void addSafePoint(GC::PointKind Kind, MCSymbol *Label, const DebugLoc &DL) {
- SafePoints.emplace_back(Kind, Label, DL);
+ void addSafePoint(MCSymbol *Label, const DebugLoc &DL) {
+ SafePoints.emplace_back(Label, DL);
}
/// getFrameSize/setFrameSize - Records the function's frame size.
diff --git a/linux-x64/clang/include/llvm/CodeGen/GCMetadataPrinter.h b/linux-x64/clang/include/llvm/CodeGen/GCMetadataPrinter.h
index 1cc69a7..f9527c9 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GCMetadataPrinter.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -29,6 +28,7 @@
class GCModuleInfo;
class GCStrategy;
class Module;
+class StackMaps;
/// GCMetadataPrinterRegistry - The GC assembly printer registry uses all the
/// defaults from Registry.
@@ -60,6 +60,11 @@
/// Called after the assembly for the module is generated by
/// the AsmPrinter (but before target specific hooks)
virtual void finishAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) {}
+
+ /// Called when the stack maps are generated. Return true if
+ /// stack maps with a custom format are generated. Otherwise
+ /// returns false and the default format will be used.
+ virtual bool emitStackMaps(StackMaps &SM, AsmPrinter &AP) { return false; }
};
} // end namespace llvm
diff --git a/linux-x64/clang/include/llvm/CodeGen/GCStrategy.h b/linux-x64/clang/include/llvm/CodeGen/GCStrategy.h
index f835bac..c573152 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GCStrategy.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -59,19 +58,6 @@
class Type;
-namespace GC {
-
-/// PointKind - Used to indicate whether the address of the call instruction
-/// or the address after the call instruction is listed in the stackmap. For
-/// most runtimes, PostCall safepoints are appropriate.
-///
-enum PointKind {
- PreCall, ///< Instr is a call instruction.
- PostCall ///< Instr is the return address of a call.
-};
-
-} // end namespace GC
-
/// GCStrategy describes a garbage collector algorithm's code generation
/// requirements, and provides overridable hooks for those needs which cannot
/// be abstractly described. GCStrategy objects must be looked up through
@@ -88,11 +74,7 @@
/// if set, none of the other options can be
/// anything but their default values.
- unsigned NeededSafePoints = 0; ///< Bitmask of required safe points.
- bool CustomReadBarriers = false; ///< Default is to insert loads.
- bool CustomWriteBarriers = false; ///< Default is to insert stores.
- bool CustomRoots = false; ///< Default is to pass through to backend.
- bool InitRoots= true; ///< If set, roots are nulled during lowering.
+ bool NeededSafePoints = false; ///< if set, calls are inferred to be safepoints
bool UsesMetadata = false; ///< If set, backend must emit metadata tables.
public:
@@ -103,16 +85,6 @@
/// name string specified on functions which use this strategy.
const std::string &getName() const { return Name; }
- /// By default, write barriers are replaced with simple store
- /// instructions. If true, you must provide a custom pass to lower
- /// calls to \@llvm.gcwrite.
- bool customWriteBarrier() const { return CustomWriteBarriers; }
-
- /// By default, read barriers are replaced with simple load
- /// instructions. If true, you must provide a custom pass to lower
- /// calls to \@llvm.gcread.
- bool customReadBarrier() const { return CustomReadBarriers; }
-
/// Returns true if this strategy is expecting the use of gc.statepoints,
/// and false otherwise.
bool useStatepoints() const { return UseStatepoints; }
@@ -135,25 +107,8 @@
*/
///@{
- /// True if safe points of any kind are required. By default, none are
- /// recorded.
- bool needsSafePoints() const { return NeededSafePoints != 0; }
-
- /// True if the given kind of safe point is required. By default, none are
- /// recorded.
- bool needsSafePoint(GC::PointKind Kind) const {
- return (NeededSafePoints & 1 << Kind) != 0;
- }
-
- /// By default, roots are left for the code generator so it can generate a
- /// stack map. If true, you must provide a custom pass to lower
- /// calls to \@llvm.gcroot.
- bool customRoots() const { return CustomRoots; }
-
- /// If set, gcroot intrinsics should initialize their allocas to null
- /// before the first use. This is necessary for most GCs and is enabled by
- /// default.
- bool initializeRoots() const { return InitRoots; }
+ /// True if safe points need to be inferred on call sites
+ bool needsSafePoints() const { return NeededSafePoints; }
/// If set, appropriate metadata tables must be emitted by the back-end
/// (assembler, JIT, or otherwise). For statepoint, this method is
diff --git a/linux-x64/clang/include/llvm/CodeGen/GCs.h b/linux-x64/clang/include/llvm/CodeGen/GCs.h
deleted file mode 100644
index 5207f80..0000000
--- a/linux-x64/clang/include/llvm/CodeGen/GCs.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//===-- GCs.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.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains hack functions to force linking in the GC components.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_GCS_H
-#define LLVM_CODEGEN_GCS_H
-
-namespace llvm {
-class GCStrategy;
-class GCMetadataPrinter;
-
-/// FIXME: Collector instances are not useful on their own. These no longer
-/// serve any purpose except to link in the plugins.
-
-/// Creates a CoreCLR-compatible garbage collector.
-void linkCoreCLRGC();
-
-/// Creates an ocaml-compatible garbage collector.
-void linkOcamlGC();
-
-/// Creates an ocaml-compatible metadata printer.
-void linkOcamlGCPrinter();
-
-/// Creates an erlang-compatible garbage collector.
-void linkErlangGC();
-
-/// Creates an erlang-compatible metadata printer.
-void linkErlangGCPrinter();
-
-/// Creates a shadow stack garbage collector. This collector requires no code
-/// generator support.
-void linkShadowStackGC();
-
-void linkStatepointExampleGC();
-}
-
-#endif
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/CSEInfo.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/CSEInfo.h
new file mode 100644
index 0000000..97f3cd5
--- /dev/null
+++ b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/CSEInfo.h
@@ -0,0 +1,236 @@
+//===- llvm/CodeGen/GlobalISel/CSEInfo.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
+//
+//===----------------------------------------------------------------------===//
+//
+/// Provides analysis for continuously CSEing during GISel passes.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CODEGEN_GLOBALISEL_CSEINFO_H
+#define LLVM_CODEGEN_GLOBALISEL_CSEINFO_H
+
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
+#include "llvm/CodeGen/GlobalISel/GISelWorkList.h"
+#include "llvm/CodeGen/GlobalISel/Utils.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Allocator.h"
+
+namespace llvm {
+
+/// A class that wraps MachineInstrs and derives from FoldingSetNode in order to
+/// be uniqued in a CSEMap. The tradeoff here is extra memory allocations for
+/// UniqueMachineInstr vs making MachineInstr bigger.
+class UniqueMachineInstr : public FoldingSetNode {
+ friend class GISelCSEInfo;
+ const MachineInstr *MI;
+ explicit UniqueMachineInstr(const MachineInstr *MI) : MI(MI) {}
+
+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 {
+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);
+};
+
+// TODO: Find a better place for this.
+// Commonly used for O0 config.
+class CSEConfigConstantOnly : public CSEConfig {
+public:
+ virtual ~CSEConfigConstantOnly() = default;
+ virtual bool shouldCSEOpc(unsigned Opc) override;
+};
+
+/// 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
+/// track instruction mutations. In such cases, recordNewInstruction should be
+/// called (for eg inside MachineIRBuilder::recordInsertion).
+/// Also because of how just the instruction can be inserted without adding any
+/// operands to the instruction, instructions are uniqued and inserted lazily.
+/// CSEInfo should assert when trying to enter an incomplete instruction into
+/// the CSEMap. There is Opcode level granularity on which instructions can be
+/// CSE'd and for now, only Generic instructions are CSEable.
+class GISelCSEInfo : public GISelChangeObserver {
+ // Make it accessible only to CSEMIRBuilder.
+ friend class CSEMIRBuilder;
+
+ BumpPtrAllocator UniqueInstrAllocator;
+ FoldingSet<UniqueMachineInstr> CSEMap;
+ MachineRegisterInfo *MRI = nullptr;
+ MachineFunction *MF = nullptr;
+ std::unique_ptr<CSEConfig> 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
+ /// MachineInstr
+ DenseMap<const MachineInstr *, UniqueMachineInstr *> InstrMapping;
+
+ /// Store instructions that are not fully formed in TemporaryInsts.
+ /// Also because CSE insertion happens lazily, we can remove insts from this
+ /// list and avoid inserting and then removing from the CSEMap.
+ GISelWorkList<8> TemporaryInsts;
+
+ // Only used in asserts.
+ DenseMap<unsigned, unsigned> OpcodeHitTable;
+
+ bool isUniqueMachineInstValid(const UniqueMachineInstr &UMI) const;
+
+ void invalidateUniqueMachineInstr(UniqueMachineInstr *UMI);
+
+ UniqueMachineInstr *getNodeIfExists(FoldingSetNodeID &ID,
+ MachineBasicBlock *MBB, void *&InsertPos);
+
+ /// Allocate and construct a new UniqueMachineInstr for MI and return.
+ UniqueMachineInstr *getUniqueInstrForMI(const MachineInstr *MI);
+
+ void insertNode(UniqueMachineInstr *UMI, void *InsertPos = nullptr);
+
+ /// Get the MachineInstr(Unique) if it exists already in the CSEMap and the
+ /// same MachineBasicBlock.
+ MachineInstr *getMachineInstrIfExists(FoldingSetNodeID &ID,
+ MachineBasicBlock *MBB,
+ void *&InsertPos);
+
+ /// Use this method to allocate a new UniqueMachineInstr for MI and insert it
+ /// into the CSEMap. MI should return true for shouldCSE(MI->getOpcode())
+ void insertInstr(MachineInstr *MI, void *InsertPos = nullptr);
+
+public:
+ GISelCSEInfo() = default;
+
+ virtual ~GISelCSEInfo();
+
+ void setMF(MachineFunction &MF);
+
+ /// Records a newly created inst in a list and lazily insert it to the CSEMap.
+ /// Sometimes, this method might be called with a partially constructed
+ /// MachineInstr,
+ // (right after BuildMI without adding any operands) - and in such cases,
+ // defer the hashing of the instruction to a later stage.
+ void recordNewInstruction(MachineInstr *MI);
+
+ /// Use this callback to inform CSE about a newly fully created instruction.
+ void handleRecordedInst(MachineInstr *MI);
+
+ /// Use this callback to insert all the recorded instructions. At this point,
+ /// all of these insts need to be fully constructed and should not be missing
+ /// any operands.
+ void handleRecordedInsts();
+
+ /// Remove this inst from the CSE map. If this inst has not been inserted yet,
+ /// it will be removed from the Tempinsts list if it exists.
+ void handleRemoveInst(MachineInstr *MI);
+
+ void releaseMemory();
+
+ void setCSEConfig(std::unique_ptr<CSEConfig> Opt) { CSEOpt = std::move(Opt); }
+
+ bool shouldCSE(unsigned Opc) const;
+
+ void analyze(MachineFunction &MF);
+
+ void countOpcodeHit(unsigned Opc);
+
+ void print();
+
+ // Observer API
+ void erasingInstr(MachineInstr &MI) override;
+ void createdInstr(MachineInstr &MI) override;
+ void changingInstr(MachineInstr &MI) override;
+ void changedInstr(MachineInstr &MI) override;
+};
+
+class TargetRegisterClass;
+class RegisterBank;
+
+// Simple builder class to easily profile properties about MIs.
+class GISelInstProfileBuilder {
+ FoldingSetNodeID &ID;
+ const MachineRegisterInfo &MRI;
+
+public:
+ GISelInstProfileBuilder(FoldingSetNodeID &ID, const MachineRegisterInfo &MRI)
+ : ID(ID), MRI(MRI) {}
+ // Profiling methods.
+ const GISelInstProfileBuilder &addNodeIDOpcode(unsigned Opc) const;
+ const GISelInstProfileBuilder &addNodeIDRegType(const LLT &Ty) const;
+ const GISelInstProfileBuilder &addNodeIDRegType(const unsigned) const;
+
+ const GISelInstProfileBuilder &
+ addNodeIDRegType(const TargetRegisterClass *RC) const;
+ const GISelInstProfileBuilder &addNodeIDRegType(const RegisterBank *RB) const;
+
+ const GISelInstProfileBuilder &addNodeIDRegNum(unsigned Reg) const;
+
+ const GISelInstProfileBuilder &addNodeIDImmediate(int64_t Imm) const;
+ const GISelInstProfileBuilder &
+ addNodeIDMBB(const MachineBasicBlock *MBB) const;
+
+ const GISelInstProfileBuilder &
+ addNodeIDMachineOperand(const MachineOperand &MO) const;
+
+ const GISelInstProfileBuilder &addNodeIDFlag(unsigned Flag) const;
+ const GISelInstProfileBuilder &addNodeID(const MachineInstr *MI) const;
+};
+
+/// Simple wrapper that does the following.
+/// 1) Lazily evaluate the MachineFunction to compute CSEable instructions.
+/// 2) Allows configuration of which instructions are CSEd through CSEConfig
+/// object. Provides a method called get which takes a CSEConfig object.
+class GISelCSEAnalysisWrapper {
+ GISelCSEInfo Info;
+ MachineFunction *MF = nullptr;
+ bool AlreadyComputed = false;
+
+public:
+ /// Takes a CSEConfig 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);
+ void setMF(MachineFunction &MFunc) { MF = &MFunc; }
+ void setComputed(bool Computed) { AlreadyComputed = Computed; }
+ void releaseMemory() { Info.releaseMemory(); }
+};
+
+/// The actual analysis pass wrapper.
+class GISelCSEAnalysisWrapperPass : public MachineFunctionPass {
+ GISelCSEAnalysisWrapper Wrapper;
+
+public:
+ static char ID;
+ GISelCSEAnalysisWrapperPass() : MachineFunctionPass(ID) {
+ initializeGISelCSEAnalysisWrapperPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+ const GISelCSEAnalysisWrapper &getCSEWrapper() const { return Wrapper; }
+ GISelCSEAnalysisWrapper &getCSEWrapper() { return Wrapper; }
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ void releaseMemory() override {
+ Wrapper.releaseMemory();
+ Wrapper.setComputed(false);
+ }
+};
+
+} // namespace llvm
+
+#endif
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/CSEMIRBuilder.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/CSEMIRBuilder.h
new file mode 100644
index 0000000..4f95335
--- /dev/null
+++ b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/CSEMIRBuilder.h
@@ -0,0 +1,109 @@
+//===-- llvm/CodeGen/GlobalISel/CSEMIRBuilder.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
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file implements a version of MachineIRBuilder which CSEs insts within
+/// a MachineBasicBlock.
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CODEGEN_GLOBALISEL_CSEMIRBUILDER_H
+#define LLVM_CODEGEN_GLOBALISEL_CSEMIRBUILDER_H
+
+#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+#include "llvm/CodeGen/GlobalISel/Utils.h"
+
+namespace llvm {
+
+/// Defines a builder that does CSE of MachineInstructions using GISelCSEInfo.
+/// Eg usage.
+///
+///
+/// GISelCSEInfo *Info =
+/// &getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEInfo(); CSEMIRBuilder
+/// CB(Builder.getState()); CB.setCSEInfo(Info); auto A = CB.buildConstant(s32,
+/// 42); auto B = CB.buildConstant(s32, 42); assert(A == B); unsigned CReg =
+/// MRI.createGenericVirtualRegister(s32); auto C = CB.buildConstant(CReg, 42);
+/// assert(C->getOpcode() == TargetOpcode::COPY);
+/// Explicitly passing in a register would materialize a copy if possible.
+/// CSEMIRBuilder also does trivial constant folding for binary ops.
+class CSEMIRBuilder : public MachineIRBuilder {
+
+ /// Returns true if A dominates B (within the same basic block).
+ /// Both iterators must be in the same basic block.
+ //
+ // TODO: Another approach for checking dominance is having two iterators and
+ // making them go towards each other until they meet or reach begin/end. Which
+ // approach is better? Should this even change dynamically? For G_CONSTANTS
+ // most of which will be at the top of the BB, the top down approach would be
+ // a better choice. Does IRTranslator placing constants at the beginning still
+ // make sense? Should this change based on Opcode?
+ bool dominates(MachineBasicBlock::const_iterator A,
+ MachineBasicBlock::const_iterator B) const;
+
+ /// For given ID, find a machineinstr in the CSE Map. If found, check if it
+ /// dominates the current insertion point and if not, move it just before the
+ /// current insertion point and return it. If not found, return Null
+ /// MachineInstrBuilder.
+ MachineInstrBuilder getDominatingInstrForID(FoldingSetNodeID &ID,
+ void *&NodeInsertPos);
+ /// Simple check if we can CSE (we have the CSEInfo) or if this Opcode is
+ /// safe to CSE.
+ bool canPerformCSEForOpc(unsigned Opc) const;
+
+ void profileDstOp(const DstOp &Op, GISelInstProfileBuilder &B) const;
+
+ void profileDstOps(ArrayRef<DstOp> Ops, GISelInstProfileBuilder &B) const {
+ for (const DstOp &Op : Ops)
+ profileDstOp(Op, B);
+ }
+
+ void profileSrcOp(const SrcOp &Op, GISelInstProfileBuilder &B) const;
+
+ void profileSrcOps(ArrayRef<SrcOp> Ops, GISelInstProfileBuilder &B) const {
+ for (const SrcOp &Op : Ops)
+ profileSrcOp(Op, B);
+ }
+
+ void profileMBBOpcode(GISelInstProfileBuilder &B, unsigned Opc) const;
+
+ void profileEverything(unsigned Opc, ArrayRef<DstOp> DstOps,
+ ArrayRef<SrcOp> SrcOps, Optional<unsigned> Flags,
+ GISelInstProfileBuilder &B) const;
+
+ // Takes a MachineInstrBuilder and inserts it into the CSEMap using the
+ // NodeInsertPos.
+ MachineInstrBuilder memoizeMI(MachineInstrBuilder MIB, void *NodeInsertPos);
+
+ // If we have can CSE an instruction, but still need to materialize to a VReg,
+ // we emit a copy from the CSE'd inst to the VReg.
+ MachineInstrBuilder generateCopiesIfRequired(ArrayRef<DstOp> DstOps,
+ MachineInstrBuilder &MIB);
+
+ // If we have can CSE an instruction, but still need to materialize to a VReg,
+ // check if we can generate copies. It's not possible to return a single MIB,
+ // while emitting copies to multiple vregs.
+ bool checkCopyToDefsPossible(ArrayRef<DstOp> DstOps);
+
+public:
+ // Pull in base class constructors.
+ using MachineIRBuilder::MachineIRBuilder;
+ // Unhide buildInstr
+ MachineInstrBuilder buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
+ ArrayRef<SrcOp> SrcOps,
+ Optional<unsigned> Flag = None) override;
+ // Bring in the other overload from the base class.
+ using MachineIRBuilder::buildConstant;
+
+ MachineInstrBuilder buildConstant(const DstOp &Res,
+ const ConstantInt &Val) override;
+
+ // Bring in the other overload from the base class.
+ using MachineIRBuilder::buildFConstant;
+ MachineInstrBuilder buildFConstant(const DstOp &Res,
+ const ConstantFP &Val) override;
+};
+} // namespace llvm
+#endif
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/CallLowering.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/CallLowering.h
index 32980ce..9b72b70 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/CallLowering.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
///
@@ -40,6 +39,7 @@
class CallLowering {
const TargetLowering *TLI;
+ virtual void anchor();
public:
struct ArgInfo {
unsigned Reg;
@@ -108,6 +108,9 @@
MachineIRBuilder &MIRBuilder;
MachineRegisterInfo &MRI;
CCAssignFn *AssignFn;
+
+ private:
+ virtual void anchor();
};
protected:
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/Combiner.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/Combiner.h
index fa49e8c..12a1f97 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/Combiner.h
+++ b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/Combiner.h
@@ -1,9 +1,8 @@
//== ----- llvm/CodeGen/GlobalISel/Combiner.h --------------------- == //
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -21,31 +20,25 @@
namespace llvm {
class MachineRegisterInfo;
class CombinerInfo;
+class GISelCSEInfo;
class TargetPassConfig;
class MachineFunction;
-class CombinerChangeObserver {
-public:
- virtual ~CombinerChangeObserver() {}
-
- /// An instruction was erased.
- virtual void erasedInstr(MachineInstr &MI) = 0;
- /// An instruction was created and inseerted into the function.
- virtual void createdInstr(MachineInstr &MI) = 0;
-};
-
class Combiner {
public:
Combiner(CombinerInfo &CombinerInfo, const TargetPassConfig *TPC);
- bool combineMachineInstrs(MachineFunction &MF);
+ /// If CSEInfo is not null, then the Combiner will setup observer for
+ /// CSEInfo and instantiate a CSEMIRBuilder. Pass nullptr if CSE is not
+ /// needed.
+ bool combineMachineInstrs(MachineFunction &MF, GISelCSEInfo *CSEInfo);
protected:
CombinerInfo &CInfo;
MachineRegisterInfo *MRI = nullptr;
const TargetPassConfig *TPC;
- MachineIRBuilder Builder;
+ std::unique_ptr<MachineIRBuilder> Builder;
};
} // End namespace llvm.
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index ee67f90..ee30ba9 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -1,9 +1,8 @@
-//== llvm/CodeGen/GlobalISel/CombinerHelper.h -------------- -*- C++ -*-==//
+//===-- 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
//
//===--------------------------------------------------------------------===//
//
@@ -20,21 +19,27 @@
namespace llvm {
-class CombinerChangeObserver;
+class GISelChangeObserver;
class MachineIRBuilder;
class MachineRegisterInfo;
class MachineInstr;
+class MachineOperand;
class CombinerHelper {
MachineIRBuilder &Builder;
MachineRegisterInfo &MRI;
- CombinerChangeObserver &Observer;
-
- void eraseInstr(MachineInstr &MI);
- void scheduleForVisit(MachineInstr &MI);
+ GISelChangeObserver &Observer;
public:
- CombinerHelper(CombinerChangeObserver &Observer, MachineIRBuilder &B);
+ CombinerHelper(GISelChangeObserver &Observer, MachineIRBuilder &B);
+
+ /// MachineRegisterInfo::replaceRegWith() and inform the observer of the changes
+ void replaceRegWith(MachineRegisterInfo &MRI, unsigned FromReg, unsigned 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;
/// If \p MI is COPY, try to combine it.
/// Returns true if MI changed.
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/CombinerInfo.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/CombinerInfo.h
index 98c5b98..3b09a8e 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/CombinerInfo.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -17,7 +16,7 @@
#include <cassert>
namespace llvm {
-class CombinerChangeObserver;
+class GISelChangeObserver;
class LegalizerInfo;
class MachineInstr;
class MachineIRBuilder;
@@ -43,7 +42,18 @@
/// illegal ops that are created.
bool LegalizeIllegalOps; // TODO: Make use of this.
const LegalizerInfo *LInfo;
- virtual bool combine(CombinerChangeObserver &Observer, MachineInstr &MI,
+
+ /// Attempt to combine instructions using MI as the root.
+ ///
+ /// Use Observer to report the creation, modification, and erasure of
+ /// instructions. GISelChangeObserver will automatically report certain
+ /// kinds of operations. These operations are:
+ /// * Instructions that are newly inserted into the MachineFunction
+ /// * Instructions that are erased from the MachineFunction.
+ ///
+ /// However, it is important to report instruction modification and this is
+ /// not automatic.
+ virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI,
MachineIRBuilder &B) const = 0;
};
} // namespace llvm
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.h
index 8d61f9a..e817d9b 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.h
+++ b/linux-x64/clang/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
@@ -15,91 +14,20 @@
namespace llvm {
-static Optional<APInt> ConstantFoldBinOp(unsigned Opcode, const unsigned Op1,
- const unsigned Op2,
- const MachineRegisterInfo &MRI) {
- auto MaybeOp1Cst = getConstantVRegVal(Op1, MRI);
- auto MaybeOp2Cst = getConstantVRegVal(Op2, MRI);
- if (MaybeOp1Cst && MaybeOp2Cst) {
- LLT Ty = MRI.getType(Op1);
- APInt C1(Ty.getSizeInBits(), *MaybeOp1Cst, true);
- APInt C2(Ty.getSizeInBits(), *MaybeOp2Cst, true);
- switch (Opcode) {
- default:
- break;
- case TargetOpcode::G_ADD:
- return C1 + C2;
- case TargetOpcode::G_AND:
- return C1 & C2;
- case TargetOpcode::G_ASHR:
- return C1.ashr(C2);
- case TargetOpcode::G_LSHR:
- return C1.lshr(C2);
- case TargetOpcode::G_MUL:
- return C1 * C2;
- case TargetOpcode::G_OR:
- return C1 | C2;
- case TargetOpcode::G_SHL:
- return C1 << C2;
- case TargetOpcode::G_SUB:
- return C1 - C2;
- case TargetOpcode::G_XOR:
- return C1 ^ C2;
- case TargetOpcode::G_UDIV:
- if (!C2.getBoolValue())
- break;
- return C1.udiv(C2);
- case TargetOpcode::G_SDIV:
- if (!C2.getBoolValue())
- break;
- return C1.sdiv(C2);
- case TargetOpcode::G_UREM:
- if (!C2.getBoolValue())
- break;
- return C1.urem(C2);
- case TargetOpcode::G_SREM:
- if (!C2.getBoolValue())
- break;
- return C1.srem(C2);
- }
- }
- return None;
-}
-
/// An MIRBuilder which does trivial constant folding of binary ops.
/// Calls to buildInstr will also try to constant fold binary ops.
-class ConstantFoldingMIRBuilder
- : public FoldableInstructionsBuilder<ConstantFoldingMIRBuilder> {
+class ConstantFoldingMIRBuilder : public MachineIRBuilder {
public:
// Pull in base class constructors.
- using FoldableInstructionsBuilder<
- ConstantFoldingMIRBuilder>::FoldableInstructionsBuilder;
- // Unhide buildInstr
- using FoldableInstructionsBuilder<ConstantFoldingMIRBuilder>::buildInstr;
+ using MachineIRBuilder::MachineIRBuilder;
- // Implement buildBinaryOp required by FoldableInstructionsBuilder which
- // tries to constant fold.
- MachineInstrBuilder buildBinaryOp(unsigned Opcode, unsigned Dst,
- unsigned Src0, unsigned Src1) {
- validateBinaryOp(Dst, Src0, Src1);
- auto MaybeCst = ConstantFoldBinOp(Opcode, Src0, Src1, getMF().getRegInfo());
- if (MaybeCst)
- return buildConstant(Dst, MaybeCst->getSExtValue());
- return buildInstr(Opcode).addDef(Dst).addUse(Src0).addUse(Src1);
- }
-
- template <typename DstTy, typename UseArg1Ty, typename UseArg2Ty>
- MachineInstrBuilder buildInstr(unsigned Opc, DstTy &&Ty, UseArg1Ty &&Arg1,
- UseArg2Ty &&Arg2) {
- unsigned Dst = getDestFromArg(Ty);
- return buildInstr(Opc, Dst, getRegFromArg(std::forward<UseArg1Ty>(Arg1)),
- getRegFromArg(std::forward<UseArg2Ty>(Arg2)));
- }
+ virtual ~ConstantFoldingMIRBuilder() = default;
// Try to provide an overload for buildInstr for binary ops in order to
// constant fold.
- MachineInstrBuilder buildInstr(unsigned Opc, unsigned Dst, unsigned Src0,
- unsigned Src1) {
+ MachineInstrBuilder buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
+ ArrayRef<SrcOp> SrcOps,
+ Optional<unsigned> Flags = None) override {
switch (Opc) {
default:
break;
@@ -116,19 +44,18 @@
case TargetOpcode::G_SDIV:
case TargetOpcode::G_UREM:
case TargetOpcode::G_SREM: {
- return buildBinaryOp(Opc, Dst, Src0, Src1);
+ assert(DstOps.size() == 1 && "Invalid dst ops");
+ assert(SrcOps.size() == 2 && "Invalid src ops");
+ const DstOp &Dst = DstOps[0];
+ const SrcOp &Src0 = SrcOps[0];
+ const SrcOp &Src1 = SrcOps[1];
+ if (auto MaybeCst =
+ ConstantFoldBinOp(Opc, Src0.getReg(), Src1.getReg(), *getMRI()))
+ return buildConstant(Dst, MaybeCst->getSExtValue());
+ break;
}
}
- return buildInstr(Opc).addDef(Dst).addUse(Src0).addUse(Src1);
- }
-
- // Fallback implementation of buildInstr.
- template <typename DstTy, typename... UseArgsTy>
- MachineInstrBuilder buildInstr(unsigned Opc, DstTy &&Ty,
- UseArgsTy &&... Args) {
- auto MIB = buildInstr(Opc).addDef(getDestFromArg(Ty));
- addUsesFromArgs(MIB, std::forward<UseArgsTy>(Args)...);
- return MIB;
+ return MachineIRBuilder::buildInstr(Opc, DstOps, SrcOps);
}
};
} // namespace llvm
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h
new file mode 100644
index 0000000..e5691cb
--- /dev/null
+++ b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h
@@ -0,0 +1,117 @@
+//===----- llvm/CodeGen/GlobalISel/GISelChangeObserver.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
+//
+//===----------------------------------------------------------------------===//
+//
+/// This contains common code to allow clients to notify changes to machine
+/// instr.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CODEGEN_GLOBALISEL_GISELCHANGEOBSERVER_H
+#define LLVM_CODEGEN_GLOBALISEL_GISELCHANGEOBSERVER_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/CodeGen/MachineFunction.h"
+
+namespace llvm {
+class MachineInstr;
+class MachineRegisterInfo;
+
+/// Abstract class that contains various methods for clients to notify about
+/// changes. This should be the preferred way for APIs to notify changes.
+/// Typically calling erasingInstr/createdInstr multiple times should not affect
+/// the result. The observer would likely need to check if it was already
+/// notified earlier (consider using GISelWorkList).
+class GISelChangeObserver {
+ SmallPtrSet<MachineInstr *, 4> ChangingAllUsesOfReg;
+
+public:
+ virtual ~GISelChangeObserver() {}
+
+ /// An instruction is about to be erased.
+ virtual void erasingInstr(MachineInstr &MI) = 0;
+
+ /// 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;
+
+ /// All the instructions using the given register are being changed.
+ /// For convenience, finishedChangingAllUsesOfReg() will report the completion
+ /// of the changes. The use list may change between this call and
+ /// finishedChangingAllUsesOfReg().
+ void changingAllUsesOfReg(const MachineRegisterInfo &MRI, unsigned Reg);
+ /// All instructions reported as changing by changingAllUsesOfReg() have
+ /// finished being changed.
+ void finishedChangingAllUsesOfReg();
+
+};
+
+/// Simple wrapper observer that takes several observers, and calls
+/// each one for each event. If there are multiple observers (say CSE,
+/// Legalizer, Combiner), it's sufficient to register this to the machine
+/// function as the delegate.
+class GISelObserverWrapper : public MachineFunction::Delegate,
+ public GISelChangeObserver {
+ SmallVector<GISelChangeObserver *, 4> Observers;
+
+public:
+ GISelObserverWrapper() = default;
+ GISelObserverWrapper(ArrayRef<GISelChangeObserver *> Obs)
+ : Observers(Obs.begin(), Obs.end()) {}
+ // Adds an observer.
+ void addObserver(GISelChangeObserver *O) { Observers.push_back(O); }
+ // Removes an observer from the list and does nothing if observer is not
+ // present.
+ void removeObserver(GISelChangeObserver *O) {
+ auto It = std::find(Observers.begin(), Observers.end(), O);
+ if (It != Observers.end())
+ Observers.erase(It);
+ }
+ // API for Observer.
+ void erasingInstr(MachineInstr &MI) override {
+ for (auto &O : Observers)
+ O->erasingInstr(MI);
+ }
+ void createdInstr(MachineInstr &MI) override {
+ for (auto &O : Observers)
+ O->createdInstr(MI);
+ }
+ void changingInstr(MachineInstr &MI) override {
+ for (auto &O : Observers)
+ O->changingInstr(MI);
+ }
+ void changedInstr(MachineInstr &MI) override {
+ for (auto &O : Observers)
+ O->changedInstr(MI);
+ }
+ // API for MachineFunction::Delegate
+ void MF_HandleInsertion(MachineInstr &MI) override { createdInstr(MI); }
+ void MF_HandleRemoval(MachineInstr &MI) override { erasingInstr(MI); }
+};
+
+/// A simple RAII based CSEInfo installer.
+/// Use this in a scope to install a delegate to the MachineFunction and reset
+/// it at the end of the scope.
+class RAIIDelegateInstaller {
+ MachineFunction &MF;
+ MachineFunction::Delegate *Delegate;
+
+public:
+ RAIIDelegateInstaller(MachineFunction &MF, MachineFunction::Delegate *Del);
+ ~RAIIDelegateInstaller();
+};
+
+} // namespace llvm
+#endif
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/GISelWorkList.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/GISelWorkList.h
index 167905d..626a666 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/GISelWorkList.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
@@ -12,38 +11,42 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/Support/Debug.h"
namespace llvm {
class MachineInstr;
+class MachineFunction;
-// Worklist which mostly works similar to InstCombineWorkList, but on MachineInstrs.
-// The main difference with something like a SetVector is that erasing an element doesn't
-// move all elements over one place - instead just nulls out the element of the vector.
-// FIXME: Does it make sense to factor out common code with the instcombinerWorkList?
+// Worklist which mostly works similar to InstCombineWorkList, but on
+// MachineInstrs. The main difference with something like a SetVector is that
+// erasing an element doesn't move all elements over one place - instead just
+// nulls out the element of the vector.
+//
+// FIXME: Does it make sense to factor out common code with the
+// instcombinerWorkList?
template<unsigned N>
class GISelWorkList {
- SmallVector<MachineInstr*, N> Worklist;
- DenseMap<MachineInstr*, unsigned> WorklistMap;
+ SmallVector<MachineInstr *, N> Worklist;
+ DenseMap<MachineInstr *, unsigned> WorklistMap;
public:
- GISelWorkList() = default;
+ GISelWorkList() : WorklistMap(N) {}
bool empty() const { return WorklistMap.empty(); }
unsigned size() const { return WorklistMap.size(); }
- /// Add - Add the specified instruction to the worklist if it isn't already
- /// in it.
+ /// Add the specified instruction to the worklist if it isn't already in it.
void insert(MachineInstr *I) {
- if (WorklistMap.try_emplace(I, Worklist.size()).second) {
+ if (WorklistMap.try_emplace(I, Worklist.size()).second)
Worklist.push_back(I);
- }
}
- /// Remove - remove I from the worklist if it exists.
- void remove(MachineInstr *I) {
+ /// Remove I from the worklist if it exists.
+ void remove(const MachineInstr *I) {
auto It = WorklistMap.find(I);
if (It == WorklistMap.end()) return; // Not in worklist.
@@ -53,6 +56,11 @@
WorklistMap.erase(It);
}
+ void clear() {
+ Worklist.clear();
+ WorklistMap.clear();
+ }
+
MachineInstr *pop_back_val() {
MachineInstr *I;
do {
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/IRTranslator.h
index 2498ee9..c75d823 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/IRTranslator.h
+++ b/linux-x64/clang/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
@@ -21,11 +20,11 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+#include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
#include "llvm/CodeGen/GlobalISel/Types.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/Support/Allocator.h"
#include "llvm/IR/Intrinsics.h"
+#include "llvm/Support/Allocator.h"
#include <memory>
#include <utility>
@@ -217,6 +216,17 @@
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);
@@ -242,6 +252,8 @@
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
@@ -300,6 +312,8 @@
bool translateFSub(const User &U, MachineIRBuilder &MIRBuilder);
+ bool translateFNeg(const User &U, MachineIRBuilder &MIRBuilder);
+
bool translateAdd(const User &U, MachineIRBuilder &MIRBuilder) {
return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
}
@@ -442,11 +456,13 @@
// I.e., compared to regular MIBuilder, this one also inserts the instruction
// in the current block, it can creates block, etc., basically a kind of
// IRBuilder, but for Machine IR.
- MachineIRBuilder CurBuilder;
+ // CSEMIRBuilder CurBuilder;
+ std::unique_ptr<MachineIRBuilder> CurBuilder;
// Builder set to the entry block (just after ABI lowering instructions). Used
// as a convenient location for Constants.
- MachineIRBuilder EntryBuilder;
+ // CSEMIRBuilder EntryBuilder;
+ std::unique_ptr<MachineIRBuilder> EntryBuilder;
// The MachineFunction currently being translated.
MachineFunction *MF;
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/InstructionSelect.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/InstructionSelect.h
index 01521c4..1af46e0 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/InstructionSelect.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
index 471def7..e4d05a5 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
index 2003a79..87ef2f8 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
index 8735876..e7680e1 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
+++ b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
@@ -1,9 +1,8 @@
-//===-- llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h --===========//
+//===-- 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
@@ -14,12 +13,14 @@
#include "llvm/CodeGen/GlobalISel/Legalizer.h"
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
+#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/GlobalISel/Utils.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/Debug.h"
#define DEBUG_TYPE "legalizer"
+using namespace llvm::MIPatternMatch;
namespace llvm {
class LegalizationArtifactCombiner {
@@ -36,15 +37,29 @@
SmallVectorImpl<MachineInstr *> &DeadInsts) {
if (MI.getOpcode() != TargetOpcode::G_ANYEXT)
return false;
- if (MachineInstr *DefMI = getOpcodeDef(TargetOpcode::G_TRUNC,
- MI.getOperand(1).getReg(), MRI)) {
+
+ Builder.setInstr(MI);
+ unsigned DstReg = MI.getOperand(0).getReg();
+ unsigned SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
+
+ // aext(trunc x) - > aext/copy/trunc x
+ unsigned TruncSrc;
+ if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;);
- unsigned DstReg = MI.getOperand(0).getReg();
- unsigned SrcReg = DefMI->getOperand(1).getReg();
- Builder.setInstr(MI);
- // We get a copy/trunc/extend depending on the sizes
- Builder.buildAnyExtOrTrunc(DstReg, SrcReg);
- markInstAndDefDead(MI, *DefMI, DeadInsts);
+ Builder.buildAnyExtOrTrunc(DstReg, TruncSrc);
+ markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
+ return true;
+ }
+
+ // aext([asz]ext x) -> [asz]ext x
+ unsigned ExtSrc;
+ MachineInstr *ExtMI;
+ if (mi_match(SrcReg, MRI,
+ m_all_of(m_MInstr(ExtMI), m_any_of(m_GAnyExt(m_Reg(ExtSrc)),
+ m_GSExt(m_Reg(ExtSrc)),
+ m_GZExt(m_Reg(ExtSrc)))))) {
+ Builder.buildInstr(ExtMI->getOpcode(), {DstReg}, {ExtSrc});
+ markInstAndDefDead(MI, *ExtMI, DeadInsts);
return true;
}
return tryFoldImplicitDef(MI, DeadInsts);
@@ -55,24 +70,25 @@
if (MI.getOpcode() != TargetOpcode::G_ZEXT)
return false;
- if (MachineInstr *DefMI = getOpcodeDef(TargetOpcode::G_TRUNC,
- MI.getOperand(1).getReg(), MRI)) {
- unsigned DstReg = MI.getOperand(0).getReg();
+
+ Builder.setInstr(MI);
+ unsigned DstReg = MI.getOperand(0).getReg();
+ unsigned SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
+
+ // zext(trunc x) - > and (aext/copy/trunc x), mask
+ unsigned 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;);
- Builder.setInstr(MI);
- unsigned ZExtSrc = MI.getOperand(1).getReg();
- LLT ZExtSrcTy = MRI.getType(ZExtSrc);
- APInt Mask = APInt::getAllOnesValue(ZExtSrcTy.getSizeInBits());
- auto MaskCstMIB = Builder.buildConstant(DstTy, Mask.getZExtValue());
- unsigned TruncSrc = DefMI->getOperand(1).getReg();
- // We get a copy/trunc/extend depending on the sizes
- auto SrcCopyOrTrunc = Builder.buildAnyExtOrTrunc(DstTy, TruncSrc);
- Builder.buildAnd(DstReg, SrcCopyOrTrunc, MaskCstMIB);
- markInstAndDefDead(MI, *DefMI, DeadInsts);
+ LLT SrcTy = MRI.getType(SrcReg);
+ 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;
}
return tryFoldImplicitDef(MI, DeadInsts);
@@ -83,33 +99,36 @@
if (MI.getOpcode() != TargetOpcode::G_SEXT)
return false;
- if (MachineInstr *DefMI = getOpcodeDef(TargetOpcode::G_TRUNC,
- MI.getOperand(1).getReg(), MRI)) {
- unsigned DstReg = MI.getOperand(0).getReg();
+
+ Builder.setInstr(MI);
+ unsigned DstReg = MI.getOperand(0).getReg();
+ unsigned SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
+
+ // sext(trunc x) - > ashr (shl (aext/copy/trunc x), c), c
+ unsigned 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;);
- Builder.setInstr(MI);
- unsigned SExtSrc = MI.getOperand(1).getReg();
- LLT SExtSrcTy = MRI.getType(SExtSrc);
- unsigned SizeDiff = DstTy.getSizeInBits() - SExtSrcTy.getSizeInBits();
- auto SizeDiffMIB = Builder.buildConstant(DstTy, SizeDiff);
- unsigned TruncSrcReg = DefMI->getOperand(1).getReg();
- // We get a copy/trunc/extend depending on the sizes
- auto SrcCopyExtOrTrunc = Builder.buildAnyExtOrTrunc(DstTy, TruncSrcReg);
- auto ShlMIB = Builder.buildInstr(TargetOpcode::G_SHL, DstTy,
- SrcCopyExtOrTrunc, SizeDiffMIB);
- Builder.buildInstr(TargetOpcode::G_ASHR, DstReg, ShlMIB, SizeDiffMIB);
- markInstAndDefDead(MI, *DefMI, DeadInsts);
+ LLT SrcTy = MRI.getType(SrcReg);
+ unsigned ShAmt = DstTy.getScalarSizeInBits() - SrcTy.getScalarSizeInBits();
+ auto MIBShAmt = Builder.buildConstant(DstTy, ShAmt);
+ auto MIBShl = Builder.buildInstr(
+ TargetOpcode::G_SHL, {DstTy},
+ {Builder.buildAnyExtOrTrunc(DstTy, TruncSrc), MIBShAmt});
+ Builder.buildInstr(TargetOpcode::G_ASHR, {DstReg}, {MIBShl, MIBShAmt});
+ markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
return true;
}
return tryFoldImplicitDef(MI, DeadInsts);
}
- /// Try to fold sb = EXTEND (G_IMPLICIT_DEF sa) -> sb = G_IMPLICIT_DEF
+ /// Try to fold G_[ASZ]EXT (G_IMPLICIT_DEF).
bool tryFoldImplicitDef(MachineInstr &MI,
SmallVectorImpl<MachineInstr *> &DeadInsts) {
unsigned Opcode = MI.getOpcode();
@@ -119,19 +138,41 @@
if (MachineInstr *DefMI = getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF,
MI.getOperand(1).getReg(), MRI)) {
+ Builder.setInstr(MI);
unsigned DstReg = MI.getOperand(0).getReg();
LLT DstTy = MRI.getType(DstReg);
- if (isInstUnsupported({TargetOpcode::G_IMPLICIT_DEF, {DstTy}}))
- return false;
- LLVM_DEBUG(dbgs() << ".. Combine EXT(IMPLICIT_DEF) " << MI;);
- Builder.setInstr(MI);
- Builder.buildInstr(TargetOpcode::G_IMPLICIT_DEF, DstReg);
+
+ if (Opcode == TargetOpcode::G_ANYEXT) {
+ // G_ANYEXT (G_IMPLICIT_DEF) -> G_IMPLICIT_DEF
+ if (isInstUnsupported({TargetOpcode::G_IMPLICIT_DEF, {DstTy}}))
+ return false;
+ LLVM_DEBUG(dbgs() << ".. Combine G_ANYEXT(G_IMPLICIT_DEF): " << MI;);
+ Builder.buildInstr(TargetOpcode::G_IMPLICIT_DEF, {DstReg}, {});
+ } 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 (isConstantUnsupported(DstTy))
+ return false;
+ LLVM_DEBUG(dbgs() << ".. Combine G_[SZ]EXT(G_IMPLICIT_DEF): " << MI;);
+ Builder.buildConstant(DstReg, 0);
+ }
+
markInstAndDefDead(MI, *DefMI, DeadInsts);
return true;
}
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) {
@@ -139,8 +180,14 @@
return false;
unsigned NumDefs = MI.getNumOperands() - 1;
- MachineInstr *MergeI = getOpcodeDef(TargetOpcode::G_MERGE_VALUES,
- MI.getOperand(NumDefs).getReg(), MRI);
+
+ LLT OpTy = MRI.getType(MI.getOperand(NumDefs).getReg());
+ LLT DestTy = MRI.getType(MI.getOperand(0).getReg());
+
+ unsigned MergingOpcode = getMergeOpcode(OpTy, DestTy);
+ MachineInstr *MergeI =
+ getOpcodeDef(MergingOpcode, MI.getOperand(NumDefs).getReg(), MRI);
+
if (!MergeI)
return false;
@@ -206,6 +253,65 @@
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
@@ -223,6 +329,8 @@
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()))
@@ -233,6 +341,23 @@
}
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
@@ -253,8 +378,8 @@
// 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) {
@@ -277,6 +402,28 @@
auto Step = LI.getAction(Query);
return Step.Action == Unsupported || Step.Action == NotFound;
}
+
+ 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;
+ while (mi_match(Reg, MRI, m_Copy(m_Reg(TmpReg)))) {
+ if (MRI.getType(TmpReg).isValid())
+ Reg = TmpReg;
+ else
+ break;
+ }
+ return Reg;
+ }
};
} // namespace llvm
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/Legalizer.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/Legalizer.h
index 8284ab6..0181650 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/Legalizer.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index 4d804d0..136356c 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -32,6 +31,7 @@
class LegalizerInfo;
class Legalizer;
class MachineRegisterInfo;
+class GISelChangeObserver;
class LegalizerHelper {
public:
@@ -48,8 +48,10 @@
UnableToLegalize,
};
- LegalizerHelper(MachineFunction &MF);
- LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI);
+ LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer,
+ MachineIRBuilder &B);
+ LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
+ GISelChangeObserver &Observer, MachineIRBuilder &B);
/// Replace \p MI by a sequence of legal instructions that can implement the
/// same operation. Note that this means \p MI may be deleted, so any iterator
@@ -84,11 +86,11 @@
/// 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
- MachineIRBuilder MIRBuilder;
+ MachineIRBuilder &MIRBuilder;
/// Expose LegalizerInfo so the clients can re-use.
const LegalizerInfo &getLegalizerInfo() const { return LI; }
@@ -102,21 +104,102 @@
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);
+
+ 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);
+ /// Version which handles irregular splits.
+ bool extractParts(unsigned Reg, LLT RegTy, LLT MainTy,
+ LLT &LeftoverTy,
+ SmallVectorImpl<unsigned> &VRegs,
+ SmallVectorImpl<unsigned> &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(unsigned DstReg, LLT ResultTy,
+ LLT PartTy, ArrayRef<unsigned> PartRegs,
+ LLT LeftoverTy = LLT(), ArrayRef<unsigned> LeftoverRegs = {});
+
+ 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
+ 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, unsigned TypeIdx, LLT Ty);
+ LegalizeResult narrowScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+ LegalizeResult narrowScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+
+ LegalizeResult narrowScalarSelect(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+
LegalizeResult lowerBitCount(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
MachineRegisterInfo &MRI;
const LegalizerInfo &LI;
+ /// To keep track of changes made by the LegalizerHelper.
+ GISelChangeObserver &Observer;
};
/// Helper function that creates the given libcall.
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
index a8c2608..5979173 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -39,6 +38,7 @@
class MachineIRBuilder;
class MachineRegisterInfo;
class MCInstrInfo;
+class GISelChangeObserver;
namespace LegalizeActions {
enum LegalizeAction : std::uint8_t {
@@ -121,7 +121,7 @@
ArrayRef<LLT> Types;
struct MemDesc {
- uint64_t Size;
+ uint64_t SizeInBits;
AtomicOrdering Ordering;
};
@@ -204,15 +204,40 @@
std::initializer_list<TypePairAndMemSize> TypesAndMemSizeInit);
/// 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
@@ -227,13 +252,25 @@
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.
@@ -596,13 +633,29 @@
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) {
@@ -611,6 +664,21 @@
Mutation);
}
+ LegalizeRuleSet &scalarize(unsigned TypeIdx) {
+ using namespace LegalityPredicates;
+ return actionIf(LegalizeAction::FewerElements, isVector(typeIdx(TypeIdx)),
+ LegalizeMutations::scalarize(TypeIdx));
+ }
+
+ /// Ensure the scalar 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 is at least as wide as Ty.
LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT &Ty) {
using namespace LegalityPredicates;
@@ -621,6 +689,15 @@
}
/// 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;
@@ -636,12 +713,12 @@
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.
@@ -651,6 +728,27 @@
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);
+ return widenScalarIf(
+ [=](const LegalityQuery &Query) {
+ return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
+ Query.Types[TypeIdx].getSizeInBits();
+ },
+ [=](const LegalityQuery &Query) {
+ LLT T = Query.Types[LargeTypeIdx];
+ return std::make_pair(TypeIdx,
+ T.isVector() ? T.getElementType() : T);
+ });
+ }
+
/// Add more elements to the vector to reach the next power of two.
/// No effect if the type is not a vector or the element count is a power of
/// two.
@@ -676,7 +774,7 @@
[=](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.
@@ -693,8 +791,8 @@
},
[=](const LegalityQuery &Query) {
LLT VecTy = Query.Types[TypeIdx];
- 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
@@ -947,9 +1045,9 @@
bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;
- virtual bool legalizeCustom(MachineInstr &MI,
- MachineRegisterInfo &MRI,
- MachineIRBuilder &MIRBuilder) const;
+ virtual bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI,
+ MachineIRBuilder &MIRBuilder,
+ GISelChangeObserver &Observer) const;
private:
/// Determine what action should be taken to legalize the given generic
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/Localizer.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/Localizer.h
index 1e2d476..cfc7c35 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/Localizer.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
index f77f9a8..1f4ee8a 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
+++ b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
@@ -1,9 +1,8 @@
//== ----- llvm/CodeGen/GlobalISel/MIPatternMatch.h --------------------- == //
//
-// 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/linux-x64/clang/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index a837cf0..6e1ff7c 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/linux-x64/clang/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
@@ -14,6 +13,7 @@
#ifndef LLVM_CODEGEN_GLOBALISEL_MACHINEIRBUILDER_H
#define LLVM_CODEGEN_GLOBALISEL_MACHINEIRBUILDER_H
+#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
#include "llvm/CodeGen/GlobalISel/Types.h"
#include "llvm/CodeGen/LowLevelType.h"
@@ -30,6 +30,7 @@
class MachineFunction;
class MachineInstr;
class TargetInstrInfo;
+class GISelChangeObserver;
/// Class which stores all the state required in a MachineIRBuilder.
/// Since MachineIRBuilders will only store state in this object, it allows
@@ -50,57 +51,175 @@
MachineBasicBlock::iterator II;
/// @}
- std::function<void(MachineInstr *)> InsertedInstr;
+ GISelChangeObserver *Observer;
+
+ GISelCSEInfo *CSEInfo;
};
+class DstOp {
+ union {
+ LLT LLTTy;
+ unsigned Reg;
+ const TargetRegisterClass *RC;
+ };
+
+public:
+ enum class DstType { Ty_LLT, Ty_Reg, Ty_RC };
+ DstOp(unsigned 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) {}
+
+ void addDefToMIB(MachineRegisterInfo &MRI, MachineInstrBuilder &MIB) const {
+ switch (Ty) {
+ case DstType::Ty_Reg:
+ MIB.addDef(Reg);
+ break;
+ case DstType::Ty_LLT:
+ MIB.addDef(MRI.createGenericVirtualRegister(LLTTy));
+ break;
+ case DstType::Ty_RC:
+ MIB.addDef(MRI.createVirtualRegister(RC));
+ break;
+ }
+ }
+
+ LLT getLLTTy(const MachineRegisterInfo &MRI) const {
+ switch (Ty) {
+ case DstType::Ty_RC:
+ return LLT{};
+ case DstType::Ty_LLT:
+ return LLTTy;
+ case DstType::Ty_Reg:
+ return MRI.getType(Reg);
+ }
+ llvm_unreachable("Unrecognised DstOp::DstType enum");
+ }
+
+ unsigned getReg() const {
+ assert(Ty == DstType::Ty_Reg && "Not a register");
+ return Reg;
+ }
+
+ const TargetRegisterClass *getRegClass() const {
+ switch (Ty) {
+ case DstType::Ty_RC:
+ return RC;
+ default:
+ llvm_unreachable("Not a RC Operand");
+ }
+ }
+
+ DstType getDstOpKind() const { return Ty; }
+
+private:
+ DstType Ty;
+};
+
+class SrcOp {
+ union {
+ MachineInstrBuilder SrcMIB;
+ unsigned Reg;
+ CmpInst::Predicate Pred;
+ };
+
+public:
+ enum class SrcType { Ty_Reg, Ty_MIB, Ty_Predicate };
+ SrcOp(unsigned 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) {}
+
+ void addSrcToMIB(MachineInstrBuilder &MIB) const {
+ switch (Ty) {
+ case SrcType::Ty_Predicate:
+ MIB.addPredicate(Pred);
+ break;
+ case SrcType::Ty_Reg:
+ MIB.addUse(Reg);
+ break;
+ case SrcType::Ty_MIB:
+ MIB.addUse(SrcMIB->getOperand(0).getReg());
+ break;
+ }
+ }
+
+ LLT getLLTTy(const MachineRegisterInfo &MRI) const {
+ switch (Ty) {
+ case SrcType::Ty_Predicate:
+ llvm_unreachable("Not a register operand");
+ case SrcType::Ty_Reg:
+ return MRI.getType(Reg);
+ case SrcType::Ty_MIB:
+ return MRI.getType(SrcMIB->getOperand(0).getReg());
+ }
+ llvm_unreachable("Unrecognised SrcOp::SrcType enum");
+ }
+
+ unsigned getReg() const {
+ switch (Ty) {
+ case SrcType::Ty_Predicate:
+ llvm_unreachable("Not a register operand");
+ case SrcType::Ty_Reg:
+ return Reg;
+ case SrcType::Ty_MIB:
+ return SrcMIB->getOperand(0).getReg();
+ }
+ llvm_unreachable("Unrecognised SrcOp::SrcType enum");
+ }
+
+ CmpInst::Predicate getPredicate() const {
+ switch (Ty) {
+ case SrcType::Ty_Predicate:
+ return Pred;
+ default:
+ llvm_unreachable("Not a register operand");
+ }
+ }
+
+ SrcType getSrcOpKind() const { return Ty; }
+
+private:
+ SrcType Ty;
+};
+
+class FlagsOp {
+ Optional<unsigned> Flags;
+
+public:
+ explicit FlagsOp(unsigned F) : Flags(F) {}
+ FlagsOp() : Flags(None) {}
+ Optional<unsigned> getFlags() const { return Flags; }
+};
/// Helper class to build MachineInstr.
/// It keeps internally the insertion point and debug location for all
/// the new instructions we want to create.
/// This information can be modify via the related setters.
-class MachineIRBuilderBase {
+class MachineIRBuilder {
MachineIRBuilderState State;
- void validateTruncExt(unsigned Dst, unsigned Src, bool IsExtend);
protected:
- unsigned getDestFromArg(unsigned Reg) { return Reg; }
- unsigned getDestFromArg(LLT Ty) {
- return getMF().getRegInfo().createGenericVirtualRegister(Ty);
- }
- unsigned getDestFromArg(const TargetRegisterClass *RC) {
- return getMF().getRegInfo().createVirtualRegister(RC);
- }
+ void validateTruncExt(const LLT &Dst, const LLT &Src, bool IsExtend);
- void addUseFromArg(MachineInstrBuilder &MIB, unsigned Reg) {
- MIB.addUse(Reg);
- }
+ void validateBinaryOp(const LLT &Res, const LLT &Op0, const LLT &Op1);
+ void validateShiftOp(const LLT &Res, const LLT &Op0, const LLT &Op1);
- void addUseFromArg(MachineInstrBuilder &MIB, const MachineInstrBuilder &UseMIB) {
- MIB.addUse(UseMIB->getOperand(0).getReg());
- }
-
- void addUsesFromArgs(MachineInstrBuilder &MIB) { }
- template<typename UseArgTy, typename ... UseArgsTy>
- void addUsesFromArgs(MachineInstrBuilder &MIB, UseArgTy &&Arg1, UseArgsTy &&... Args) {
- addUseFromArg(MIB, Arg1);
- addUsesFromArgs(MIB, std::forward<UseArgsTy>(Args)...);
- }
- unsigned getRegFromArg(unsigned Reg) { return Reg; }
- unsigned getRegFromArg(const MachineInstrBuilder &MIB) {
- return MIB->getOperand(0).getReg();
- }
-
- void validateBinaryOp(unsigned Res, unsigned Op0, unsigned Op1);
+ void validateSelectOp(const LLT &ResTy, const LLT &TstTy, const LLT &Op0Ty,
+ const LLT &Op1Ty);
+ void recordInsertion(MachineInstr *MI) const;
public:
/// Some constructors for easy use.
- MachineIRBuilderBase() = default;
- MachineIRBuilderBase(MachineFunction &MF) { setMF(MF); }
- MachineIRBuilderBase(MachineInstr &MI) : MachineIRBuilderBase(*MI.getMF()) {
+ MachineIRBuilder() = default;
+ MachineIRBuilder(MachineFunction &MF) { setMF(MF); }
+ MachineIRBuilder(MachineInstr &MI) : MachineIRBuilder(*MI.getMF()) {
setInstr(MI);
}
- MachineIRBuilderBase(const MachineIRBuilderState &BState) : State(BState) {}
+ virtual ~MachineIRBuilder() = default;
+
+ MachineIRBuilder(const MachineIRBuilderState &BState) : State(BState) {}
const TargetInstrInfo &getTII() {
assert(State.TII && "TargetInstrInfo is not set");
@@ -113,21 +232,35 @@
return *State.MF;
}
+ const MachineFunction &getMF() const {
+ assert(State.MF && "MachineFunction is not set");
+ return *State.MF;
+ }
+
/// Getter for DebugLoc
const DebugLoc &getDL() { return State.DL; }
/// Getter for MRI
MachineRegisterInfo *getMRI() { return State.MRI; }
+ const MachineRegisterInfo *getMRI() const { return State.MRI; }
/// Getter for the State
MachineIRBuilderState &getState() { return State; }
/// Getter for the basic block we currently build.
- MachineBasicBlock &getMBB() {
+ const MachineBasicBlock &getMBB() const {
assert(State.MBB && "MachineBasicBlock is not set");
return *State.MBB;
}
+ MachineBasicBlock &getMBB() {
+ return const_cast<MachineBasicBlock &>(
+ const_cast<const MachineIRBuilder *>(this)->getMBB());
+ }
+
+ GISelCSEInfo *getCSEInfo() { return State.CSEInfo; }
+ const GISelCSEInfo *getCSEInfo() const { return State.CSEInfo; }
+
/// Current insertion point for new instructions.
MachineBasicBlock::iterator getInsertPt() { return State.II; }
@@ -137,10 +270,12 @@
void setInsertPt(MachineBasicBlock &MBB, MachineBasicBlock::iterator II);
/// @}
+ void setCSEInfo(GISelCSEInfo *Info);
+
/// \name Setters for the insertion point.
/// @{
/// Set the MachineFunction where to build instructions.
- void setMF(MachineFunction &);
+ void setMF(MachineFunction &MF);
/// Set the insertion point to the end of \p MBB.
/// \pre \p MBB must be contained by getMF().
@@ -151,12 +286,8 @@
void setInstr(MachineInstr &MI);
/// @}
- /// \name Control where instructions we create are recorded (typically for
- /// visiting again later during legalization).
- /// @{
- void recordInsertion(MachineInstr *InsertedInstr) const;
- void recordInsertions(std::function<void(MachineInstr *)> InsertedInstr);
- void stopRecordingInsertions();
+ void setChangeObserver(GISelChangeObserver &Observer);
+ void stopObservingChanges();
/// @}
/// Set the debug location to \p DL for all the next build instructions.
@@ -300,9 +431,9 @@
/// registers with the same scalar type (typically s1)
///
/// \return The newly created instruction.
- MachineInstrBuilder buildUAdde(unsigned Res, unsigned CarryOut, unsigned Op0,
- unsigned Op1, unsigned CarryIn);
-
+ MachineInstrBuilder buildUAdde(const DstOp &Res, const DstOp &CarryOut,
+ const SrcOp &Op0, const SrcOp &Op1,
+ const SrcOp &CarryIn);
/// Build and insert \p Res = G_ANYEXT \p Op0
///
@@ -318,11 +449,7 @@
///
/// \return The newly created instruction.
- MachineInstrBuilder buildAnyExt(unsigned Res, unsigned Op);
- template <typename DstType, typename ArgType>
- MachineInstrBuilder buildAnyExt(DstType &&Res, ArgType &&Arg) {
- return buildAnyExt(getDestFromArg(Res), getRegFromArg(Arg));
- }
+ MachineInstrBuilder buildAnyExt(const DstOp &Res, const SrcOp &Op);
/// Build and insert \p Res = G_SEXT \p Op
///
@@ -336,11 +463,16 @@
/// \pre \p Op must be smaller than \p Res
///
/// \return The newly created instruction.
- template <typename DstType, typename ArgType>
- MachineInstrBuilder buildSExt(DstType &&Res, ArgType &&Arg) {
- return buildSExt(getDestFromArg(Res), getRegFromArg(Arg));
- }
- MachineInstrBuilder buildSExt(unsigned Res, unsigned Op);
+ MachineInstrBuilder buildSExt(const DstOp &Res, const SrcOp &Op);
+
+ /// \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
///
@@ -354,11 +486,7 @@
/// \pre \p Op must be smaller than \p Res
///
/// \return The newly created instruction.
- template <typename DstType, typename ArgType>
- MachineInstrBuilder buildZExt(DstType &&Res, ArgType &&Arg) {
- return buildZExt(getDestFromArg(Res), getRegFromArg(Arg));
- }
- MachineInstrBuilder buildZExt(unsigned Res, unsigned Op);
+ MachineInstrBuilder buildZExt(const DstOp &Res, const SrcOp &Op);
/// Build and insert \p Res = G_SEXT \p Op, \p Res = G_TRUNC \p Op, or
/// \p Res = COPY \p Op depending on the differing sizes of \p Res and \p Op.
@@ -368,11 +496,7 @@
/// \pre \p Op must be a generic virtual register with scalar or vector type.
///
/// \return The newly created instruction.
- template <typename DstTy, typename UseArgTy>
- MachineInstrBuilder buildSExtOrTrunc(DstTy &&Dst, UseArgTy &&Use) {
- return buildSExtOrTrunc(getDestFromArg(Dst), getRegFromArg(Use));
- }
- MachineInstrBuilder buildSExtOrTrunc(unsigned Res, unsigned Op);
+ MachineInstrBuilder buildSExtOrTrunc(const DstOp &Res, const SrcOp &Op);
/// Build and insert \p Res = G_ZEXT \p Op, \p Res = G_TRUNC \p Op, or
/// \p Res = COPY \p Op depending on the differing sizes of \p Res and \p Op.
@@ -382,11 +506,7 @@
/// \pre \p Op must be a generic virtual register with scalar or vector type.
///
/// \return The newly created instruction.
- template <typename DstTy, typename UseArgTy>
- MachineInstrBuilder buildZExtOrTrunc(DstTy &&Dst, UseArgTy &&Use) {
- return buildZExtOrTrunc(getDestFromArg(Dst), getRegFromArg(Use));
- }
- MachineInstrBuilder buildZExtOrTrunc(unsigned Res, unsigned Op);
+ MachineInstrBuilder buildZExtOrTrunc(const DstOp &Res, const SrcOp &Op);
// Build and insert \p Res = G_ANYEXT \p Op, \p Res = G_TRUNC \p Op, or
/// \p Res = COPY \p Op depending on the differing sizes of \p Res and \p Op.
@@ -396,11 +516,7 @@
/// \pre \p Op must be a generic virtual register with scalar or vector type.
///
/// \return The newly created instruction.
- template <typename DstTy, typename UseArgTy>
- MachineInstrBuilder buildAnyExtOrTrunc(DstTy &&Dst, UseArgTy &&Use) {
- return buildAnyExtOrTrunc(getDestFromArg(Dst), getRegFromArg(Use));
- }
- MachineInstrBuilder buildAnyExtOrTrunc(unsigned Res, unsigned Op);
+ MachineInstrBuilder buildAnyExtOrTrunc(const DstOp &Res, const SrcOp &Op);
/// Build and insert \p Res = \p ExtOpc, \p Res = G_TRUNC \p
/// Op, or \p Res = COPY \p Op depending on the differing sizes of \p Res and
@@ -411,15 +527,11 @@
/// \pre \p Op must be a generic virtual register with scalar or vector type.
///
/// \return The newly created instruction.
- MachineInstrBuilder buildExtOrTrunc(unsigned ExtOpc, unsigned Res,
- unsigned Op);
+ MachineInstrBuilder buildExtOrTrunc(unsigned ExtOpc, const DstOp &Res,
+ const SrcOp &Op);
/// Build and insert an appropriate cast between two registers of equal size.
- template <typename DstType, typename ArgType>
- MachineInstrBuilder buildCast(DstType &&Res, ArgType &&Arg) {
- return buildCast(getDestFromArg(Res), getRegFromArg(Arg));
- }
- MachineInstrBuilder buildCast(unsigned Dst, unsigned Src);
+ MachineInstrBuilder buildCast(const DstOp &Dst, const SrcOp &Src);
/// Build and insert G_BR \p Dest
///
@@ -464,7 +576,8 @@
/// type.
///
/// \return The newly created instruction.
- MachineInstrBuilder buildConstant(unsigned Res, const ConstantInt &Val);
+ virtual MachineInstrBuilder buildConstant(const DstOp &Res,
+ const ConstantInt &Val);
/// Build and insert \p Res = G_CONSTANT \p Val
///
@@ -474,12 +587,9 @@
/// \pre \p Res must be a generic virtual register with scalar type.
///
/// \return The newly created instruction.
- MachineInstrBuilder buildConstant(unsigned Res, int64_t Val);
+ MachineInstrBuilder buildConstant(const DstOp &Res, int64_t Val);
+ MachineInstrBuilder buildConstant(const DstOp &Res, const APInt &Val);
- template <typename DstType>
- MachineInstrBuilder buildConstant(DstType &&Res, int64_t Val) {
- return buildConstant(getDestFromArg(Res), Val);
- }
/// Build and insert \p Res = G_FCONSTANT \p Val
///
/// G_FCONSTANT is a floating-point constant with the specified size and
@@ -489,17 +599,10 @@
/// \pre \p Res must be a generic virtual register with scalar type.
///
/// \return The newly created instruction.
- template <typename DstType>
- MachineInstrBuilder buildFConstant(DstType &&Res, const ConstantFP &Val) {
- return buildFConstant(getDestFromArg(Res), Val);
- }
- MachineInstrBuilder buildFConstant(unsigned Res, const ConstantFP &Val);
+ virtual MachineInstrBuilder buildFConstant(const DstOp &Res,
+ const ConstantFP &Val);
- template <typename DstType>
- MachineInstrBuilder buildFConstant(DstType &&Res, double Val) {
- return buildFConstant(getDestFromArg(Res), Val);
- }
- MachineInstrBuilder buildFConstant(unsigned Res, double Val);
+ MachineInstrBuilder buildFConstant(const DstOp &Res, double Val);
/// Build and insert \p Res = COPY Op
///
@@ -508,11 +611,7 @@
/// \pre setBasicBlock or setMI must have been called.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildCopy(unsigned Res, unsigned Op);
- template <typename DstType, typename SrcType>
- MachineInstrBuilder buildCopy(DstType &&Res, SrcType &&Src) {
- return buildCopy(getDestFromArg(Res), getRegFromArg(Src));
- }
+ MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op);
/// Build and insert `Res = G_LOAD Addr, MMO`.
///
@@ -559,10 +658,7 @@
MachineInstrBuilder buildExtract(unsigned Res, unsigned Src, uint64_t Index);
/// Build and insert \p Res = IMPLICIT_DEF.
- template <typename DstType> MachineInstrBuilder buildUndef(DstType &&Res) {
- return buildUndef(getDestFromArg(Res));
- }
- MachineInstrBuilder buildUndef(unsigned Res);
+ MachineInstrBuilder buildUndef(const DstOp &Res);
/// Build and insert instructions to put \p Ops together at the specified p
/// Indices to form a larger register.
@@ -591,7 +687,7 @@
/// \pre The type of all \p Ops registers must be identical.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildMerge(unsigned Res, ArrayRef<unsigned> Ops);
+ MachineInstrBuilder buildMerge(const DstOp &Res, ArrayRef<unsigned> Ops);
/// Build and insert \p Res0, ... = G_UNMERGE_VALUES \p Op
///
@@ -603,7 +699,55 @@
/// \pre The type of all \p Res registers must be identical.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildUnmerge(ArrayRef<unsigned> Res, unsigned Op);
+ MachineInstrBuilder buildUnmerge(ArrayRef<LLT> Res, const SrcOp &Op);
+ MachineInstrBuilder buildUnmerge(ArrayRef<unsigned> Res, const SrcOp &Op);
+
+ /// Build and insert \p Res = G_BUILD_VECTOR \p Op0, ...
+ ///
+ /// G_BUILD_VECTOR creates a vector value from multiple scalar registers.
+ /// \pre setBasicBlock or setMI must have been called.
+ /// \pre The entire register \p Res (and no more) must be covered by the
+ /// input scalar registers.
+ /// \pre The type of all \p Ops registers must be identical.
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildBuildVector(const DstOp &Res,
+ ArrayRef<unsigned> 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, ...
+ ///
+ /// G_BUILD_VECTOR_TRUNC creates a vector value from multiple scalar registers
+ /// which have types larger than the destination vector element type, and
+ /// truncates the values to fit.
+ ///
+ /// If the operands given are already the same size as the vector elt type,
+ /// then this method will instead create a G_BUILD_VECTOR instruction.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ /// \pre The type of all \p Ops registers must be identical.
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildBuildVectorTrunc(const DstOp &Res,
+ ArrayRef<unsigned> Ops);
+
+ /// Build and insert \p Res = G_CONCAT_VECTORS \p Op0, ...
+ ///
+ /// G_CONCAT_VECTORS creates a vector from the concatenation of 2 or more
+ /// vectors.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ /// \pre The entire register \p Res (and no more) must be covered by the input
+ /// registers.
+ /// \pre The type of all source operands must be identical.
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildConcatVectors(const DstOp &Res,
+ ArrayRef<unsigned> Ops);
MachineInstrBuilder buildInsert(unsigned Res, unsigned Src,
unsigned Op, unsigned Index);
@@ -631,11 +775,7 @@
/// \pre \p Res must be smaller than \p Op
///
/// \return The newly created instruction.
- template <typename DstType, typename SrcType>
- MachineInstrBuilder buildFPTrunc(DstType &&Res, SrcType &&Src) {
- return buildFPTrunc(getDestFromArg(Res), getRegFromArg(Src));
- }
- MachineInstrBuilder buildFPTrunc(unsigned Res, unsigned Op);
+ MachineInstrBuilder buildFPTrunc(const DstOp &Res, const SrcOp &Op);
/// Build and insert \p Res = G_TRUNC \p Op
///
@@ -648,11 +788,7 @@
/// \pre \p Res must be smaller than \p Op
///
/// \return The newly created instruction.
- MachineInstrBuilder buildTrunc(unsigned Res, unsigned Op);
- template <typename DstType, typename SrcType>
- MachineInstrBuilder buildTrunc(DstType &&Res, SrcType &&Src) {
- return buildTrunc(getDestFromArg(Res), getRegFromArg(Src));
- }
+ MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op);
/// Build and insert a \p Res = G_ICMP \p Pred, \p Op0, \p Op1
///
@@ -666,13 +802,8 @@
/// \pre \p Pred must be an integer predicate.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildICmp(CmpInst::Predicate Pred,
- unsigned Res, unsigned Op0, unsigned Op1);
- template <typename DstTy, typename... UseArgsTy>
- MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, DstTy &&Dst,
- UseArgsTy &&... UseArgs) {
- return buildICmp(Pred, getDestFromArg(Dst), getRegFromArg(UseArgs)...);
- }
+ MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res,
+ const SrcOp &Op0, const SrcOp &Op1);
/// Build and insert a \p Res = G_FCMP \p Pred\p Op0, \p Op1
///
@@ -686,8 +817,8 @@
/// \pre \p Pred must be a floating-point predicate.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildFCmp(CmpInst::Predicate Pred,
- unsigned Res, unsigned Op0, unsigned Op1);
+ MachineInstrBuilder buildFCmp(CmpInst::Predicate Pred, const DstOp &Res,
+ const SrcOp &Op0, const SrcOp &Op1);
/// Build and insert a \p Res = G_SELECT \p Tst, \p Op0, \p Op1
///
@@ -699,12 +830,8 @@
/// elements as the other parameters.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildSelect(unsigned Res, unsigned Tst,
- unsigned Op0, unsigned Op1);
- template <typename DstTy, typename... UseArgsTy>
- MachineInstrBuilder buildSelect(DstTy &&Dst, UseArgsTy &&... UseArgs) {
- return buildSelect(getDestFromArg(Dst), getRegFromArg(UseArgs)...);
- }
+ MachineInstrBuilder buildSelect(const DstOp &Res, const SrcOp &Tst,
+ const SrcOp &Op0, const SrcOp &Op1);
/// Build and insert \p Res = G_INSERT_VECTOR_ELT \p Val,
/// \p Elt, \p Idx
@@ -716,8 +843,10 @@
/// with scalar type.
///
/// \return The newly created instruction.
- MachineInstrBuilder buildInsertVectorElement(unsigned Res, unsigned Val,
- unsigned Elt, unsigned Idx);
+ MachineInstrBuilder buildInsertVectorElement(const DstOp &Res,
+ const SrcOp &Val,
+ const SrcOp &Elt,
+ const SrcOp &Idx);
/// Build and insert \p Res = G_EXTRACT_VECTOR_ELT \p Val, \p Idx
///
@@ -727,8 +856,9 @@
/// \pre \p Idx must be a generic virtual register with scalar type.
///
/// \return The newly created instruction.
- MachineInstrBuilder buildExtractVectorElement(unsigned Res, unsigned Val,
- unsigned Idx);
+ MachineInstrBuilder buildExtractVectorElement(const DstOp &Res,
+ const SrcOp &Val,
+ const SrcOp &Idx);
/// Build and insert `OldValRes<def>, SuccessRes<def> =
/// G_ATOMIC_CMPXCHG_WITH_SUCCESS Addr, CmpVal, NewVal, MMO`.
@@ -965,19 +1095,7 @@
///
/// \return The newly created instruction.
MachineInstrBuilder buildBlockAddress(unsigned Res, const BlockAddress *BA);
-};
-/// A CRTP class that contains methods for building instructions that can
-/// be constant folded. MachineIRBuilders that want to inherit from this will
-/// need to implement buildBinaryOp (for constant folding binary ops).
-/// Alternatively, they can implement buildInstr(Opc, Dst, Uses...) to perform
-/// additional folding for Opc.
-template <typename Base>
-class FoldableInstructionsBuilder : public MachineIRBuilderBase {
- Base &base() { return static_cast<Base &>(*this); }
-
-public:
- using MachineIRBuilderBase::MachineIRBuilderBase;
/// Build and insert \p Res = G_ADD \p Op0, \p Op1
///
/// G_ADD sets \p Res to the sum of integer parameters \p Op0 and \p Op1,
@@ -989,13 +1107,10 @@
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildAdd(unsigned Dst, unsigned Src0, unsigned Src1) {
- return base().buildBinaryOp(TargetOpcode::G_ADD, Dst, Src0, Src1);
- }
- template <typename DstTy, typename... UseArgsTy>
- MachineInstrBuilder buildAdd(DstTy &&Ty, UseArgsTy &&... UseArgs) {
- unsigned Res = base().getDestFromArg(Ty);
- return base().buildAdd(Res, (base().getRegFromArg(UseArgs))...);
+ MachineInstrBuilder buildAdd(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_ADD, {Dst}, {Src0, Src1}, Flags);
}
/// Build and insert \p Res = G_SUB \p Op0, \p Op1
@@ -1009,13 +1124,10 @@
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildSub(unsigned Dst, unsigned Src0, unsigned Src1) {
- return base().buildBinaryOp(TargetOpcode::G_SUB, Dst, Src0, Src1);
- }
- template <typename DstTy, typename... UseArgsTy>
- MachineInstrBuilder buildSub(DstTy &&Ty, UseArgsTy &&... UseArgs) {
- unsigned Res = base().getDestFromArg(Ty);
- return base().buildSub(Res, (base().getRegFromArg(UseArgs))...);
+ MachineInstrBuilder buildSub(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_SUB, {Dst}, {Src0, Src1}, Flags);
}
/// Build and insert \p Res = G_MUL \p Op0, \p Op1
@@ -1028,13 +1140,40 @@
/// with the same (scalar or vector) type).
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildMul(unsigned Dst, unsigned Src0, unsigned Src1) {
- return base().buildBinaryOp(TargetOpcode::G_MUL, Dst, Src0, Src1);
+ MachineInstrBuilder buildMul(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_MUL, {Dst}, {Src0, Src1}, Flags);
}
- template <typename DstTy, typename... UseArgsTy>
- MachineInstrBuilder buildMul(DstTy &&Ty, UseArgsTy &&... UseArgs) {
- unsigned Res = base().getDestFromArg(Ty);
- return base().buildMul(Res, (base().getRegFromArg(UseArgs))...);
+
+ 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
@@ -1048,13 +1187,9 @@
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildAnd(unsigned Dst, unsigned Src0, unsigned Src1) {
- return base().buildBinaryOp(TargetOpcode::G_AND, Dst, Src0, Src1);
- }
- template <typename DstTy, typename... UseArgsTy>
- MachineInstrBuilder buildAnd(DstTy &&Ty, UseArgsTy &&... UseArgs) {
- unsigned Res = base().getDestFromArg(Ty);
- return base().buildAnd(Res, (base().getRegFromArg(UseArgs))...);
+ MachineInstrBuilder buildAnd(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1) {
+ return buildInstr(TargetOpcode::G_AND, {Dst}, {Src0, Src1});
}
/// Build and insert \p Res = G_OR \p Op0, \p Op1
@@ -1067,39 +1202,14 @@
/// with the same (scalar or vector) type).
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildOr(unsigned Dst, unsigned Src0, unsigned Src1) {
- return base().buildBinaryOp(TargetOpcode::G_OR, Dst, Src0, Src1);
+ MachineInstrBuilder buildOr(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1) {
+ return buildInstr(TargetOpcode::G_OR, {Dst}, {Src0, Src1});
}
- template <typename DstTy, typename... UseArgsTy>
- MachineInstrBuilder buildOr(DstTy &&Ty, UseArgsTy &&... UseArgs) {
- unsigned Res = base().getDestFromArg(Ty);
- return base().buildOr(Res, (base().getRegFromArg(UseArgs))...);
- }
-};
-class MachineIRBuilder : public FoldableInstructionsBuilder<MachineIRBuilder> {
-public:
- using FoldableInstructionsBuilder<
- MachineIRBuilder>::FoldableInstructionsBuilder;
- MachineInstrBuilder buildBinaryOp(unsigned Opcode, unsigned Dst,
- unsigned Src0, unsigned Src1) {
- validateBinaryOp(Dst, Src0, Src1);
- return buildInstr(Opcode).addDef(Dst).addUse(Src0).addUse(Src1);
- }
- using FoldableInstructionsBuilder<MachineIRBuilder>::buildInstr;
- /// DAG like Generic method for building arbitrary instructions as above.
- /// \Opc opcode for the instruction.
- /// \Ty Either LLT/TargetRegisterClass/unsigned types for Dst
- /// \Args Variadic list of uses of types(unsigned/MachineInstrBuilder)
- /// Uses of type MachineInstrBuilder will perform
- /// getOperand(0).getReg() to convert to register.
- template <typename DstTy, typename... UseArgsTy>
- MachineInstrBuilder buildInstr(unsigned Opc, DstTy &&Ty,
- UseArgsTy &&... Args) {
- auto MIB = buildInstr(Opc).addDef(getDestFromArg(Ty));
- addUsesFromArgs(MIB, std::forward<UseArgsTy>(Args)...);
- return MIB;
- }
+ virtual MachineInstrBuilder buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
+ ArrayRef<SrcOp> SrcOps,
+ Optional<unsigned> Flags = None);
};
} // End namespace llvm.
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/RegBankSelect.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/RegBankSelect.h
index c53ae41..c31ca5c 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/RegBankSelect.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/RegisterBank.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/RegisterBank.h
index d5612e1..f528d1a 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/RegisterBank.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
index 82fd7ed..37a63d1 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -103,8 +102,8 @@
/// Currently the TableGen-like file would look like:
/// \code
/// PartialMapping[] = {
- /// /*32-bit add*/ {0, 32, GPR},
- /// /*2x32-bit add*/ {0, 32, GPR}, {0, 32, GPR}, // <-- Same entry 3x
+ /// /*32-bit add*/ {0, 32, GPR}, // Scalar entry repeated for first vec elt.
+ /// /*2x32-bit add*/ {0, 32, GPR}, {32, 32, GPR},
/// /*<2x32-bit> vadd {0, 64, VPR}
/// }; // PartialMapping duplicated.
///
@@ -118,14 +117,15 @@
/// With the array of pointer, we would have:
/// \code
/// PartialMapping[] = {
- /// /*32-bit add*/ {0, 32, GPR},
+ /// /*32-bit add lower */ {0, 32, GPR},
+ /// /*32-bit add upper */ {32, 32, GPR},
/// /*<2x32-bit> vadd {0, 64, VPR}
/// }; // No more duplication.
///
/// BreakDowns[] = {
/// /*AddBreakDown*/ &PartialMapping[0],
- /// /*2xAddBreakDown*/ &PartialMapping[0], &PartialMapping[0],
- /// /*VAddBreakDown*/ &PartialMapping[1]
+ /// /*2xAddBreakDown*/ &PartialMapping[0], &PartialMapping[1],
+ /// /*VAddBreakDown*/ &PartialMapping[2]
/// }; // Addresses of PartialMapping duplicated (smaller).
///
/// ValueMapping[] {
@@ -160,6 +160,10 @@
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; }
@@ -617,6 +621,15 @@
return &A != &B;
}
+ /// 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.
diff --git a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/Types.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/Types.h
index 7b22e34..4fd7043 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/Types.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/GlobalISel/Utils.h b/linux-x64/clang/include/llvm/CodeGen/GlobalISel/Utils.h
index 51e3a27..dd14a0c 100644
--- a/linux-x64/clang/include/llvm/CodeGen/GlobalISel/Utils.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -108,5 +107,8 @@
/// fallback.
void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU);
+Optional<APInt> ConstantFoldBinOp(unsigned Opcode, const unsigned Op1,
+ const unsigned Op2,
+ const MachineRegisterInfo &MRI);
} // End namespace llvm.
#endif
diff --git a/linux-x64/clang/include/llvm/CodeGen/ISDOpcodes.h b/linux-x64/clang/include/llvm/CodeGen/ISDOpcodes.h
index ec9c461..ed4bfe7 100644
--- a/linux-x64/clang/include/llvm/CodeGen/ISDOpcodes.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -70,7 +69,7 @@
/// of the frame or return address to return. An index of zero corresponds
/// to the current function's frame or return address, an index of one to
/// the parent's frame or return address, and so on.
- FRAMEADDR, RETURNADDR, ADDROFRETURNADDR,
+ FRAMEADDR, RETURNADDR, ADDROFRETURNADDR, SPONENTRY,
/// LOCAL_RECOVER - Represents the llvm.localrecover intrinsic.
/// Materializes the offset from the local object pointer of another
@@ -256,6 +255,29 @@
/// Same for multiplication.
SMULO, UMULO,
+ /// RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2
+ /// integers with the same bit width (W). If the true value of LHS + RHS
+ /// exceeds the largest value that can be represented by W bits, the
+ /// resulting value is this maximum value. Otherwise, if this value is less
+ /// than the smallest value that can be represented by W bits, the
+ /// resulting value is this minimum value.
+ SADDSAT, UADDSAT,
+
+ /// RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2
+ /// integers with the same bit width (W). If the true value of LHS - RHS
+ /// exceeds the largest value that can be represented by W bits, the
+ /// resulting value is this maximum value. Otherwise, if this value is less
+ /// than the smallest value that can be represented by W bits, the
+ /// resulting value is this minimum value.
+ SSUBSAT, USUBSAT,
+
+ /// 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, UMULFIX,
+
/// Simple binary floating point operators.
FADD, FSUB, FMUL, FDIV, FREM,
@@ -272,7 +294,8 @@
/// They are used to limit optimizations while the DAG is being optimized.
STRICT_FSQRT, STRICT_FPOW, STRICT_FPOWI, STRICT_FSIN, STRICT_FCOS,
STRICT_FEXP, STRICT_FEXP2, STRICT_FLOG, STRICT_FLOG10, STRICT_FLOG2,
- STRICT_FRINT, STRICT_FNEARBYINT,
+ STRICT_FRINT, STRICT_FNEARBYINT, STRICT_FMAXNUM, STRICT_FMINNUM,
+ STRICT_FCEIL, STRICT_FFLOOR, STRICT_FROUND, STRICT_FTRUNC,
/// FMA - Perform a * b + c with no intermediate rounding step.
FMA,
@@ -377,9 +400,13 @@
/// When the 1st operand is a vector, the shift amount must be in the same
/// type. (TLI.getShiftAmountTy() will return the same type when the input
/// type is a vector.)
- /// For rotates, the shift amount is treated as an unsigned amount modulo
- /// the element size of the first operand.
- SHL, SRA, SRL, ROTL, ROTR,
+ /// For rotates and funnel shifts, the shift amount is treated as an unsigned
+ /// amount modulo the element size of the first operand.
+ ///
+ /// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
+ /// fshl(X,Y,Z): (X << (Z % BW)) | (Y >> (BW - (Z % BW)))
+ /// fshr(X,Y,Z): (X << (BW - (Z % BW))) | (Y >> (Z % BW))
+ SHL, SRA, SRL, ROTL, ROTR, FSHL, FSHR,
/// Byte Swap and Counting operators.
BSWAP, CTTZ, CTLZ, CTPOP, BITREVERSE,
@@ -461,31 +488,33 @@
/// in-register any-extension of the low lanes of an integer vector. The
/// result type must have fewer elements than the operand type, and those
/// elements must be larger integer types such that the total size of the
- /// operand type and the result type match. Each of the low operand
- /// elements is any-extended into the corresponding, wider result
- /// elements with the high bits becoming undef.
+ /// operand type is less than or equal to the size of the result type. Each
+ /// of the low operand elements is any-extended into the corresponding,
+ /// wider result elements with the high bits becoming undef.
+ /// NOTE: The type legalizer prefers to make the operand and result size
+ /// the same to allow expansion to shuffle vector during op legalization.
ANY_EXTEND_VECTOR_INREG,
/// SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an
/// in-register sign-extension of the low lanes of an integer vector. The
/// result type must have fewer elements than the operand type, and those
/// elements must be larger integer types such that the total size of the
- /// operand type and the result type match. Each of the low operand
- /// elements is sign-extended into the corresponding, wider result
- /// elements.
- // FIXME: The SIGN_EXTEND_INREG node isn't specifically limited to
- // scalars, but it also doesn't handle vectors well. Either it should be
- // restricted to scalars or this node (and its handling) should be merged
- // into it.
+ /// operand type is less than or equal to the size of the result type. Each
+ /// of the low operand elements is sign-extended into the corresponding,
+ /// wider result elements.
+ /// NOTE: The type legalizer prefers to make the operand and result size
+ /// the same to allow expansion to shuffle vector during op legalization.
SIGN_EXTEND_VECTOR_INREG,
/// ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an
/// in-register zero-extension of the low lanes of an integer vector. The
/// result type must have fewer elements than the operand type, and those
/// elements must be larger integer types such that the total size of the
- /// operand type and the result type match. Each of the low operand
- /// elements is zero-extended into the corresponding, wider result
- /// elements.
+ /// operand type is less than or equal to the size of the result type. Each
+ /// of the low operand elements is zero-extended into the corresponding,
+ /// wider result elements.
+ /// NOTE: The type legalizer prefers to make the operand and result size
+ /// the same to allow expansion to shuffle vector during op legalization.
ZERO_EXTEND_VECTOR_INREG,
/// FP_TO_[US]INT - Convert a floating point value to a signed or unsigned
@@ -550,19 +579,31 @@
/// 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,
/// FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two
/// values.
- /// In the case where a single input is NaN, the non-NaN input is returned.
+ //
+ /// In the case where a single input is a NaN (either signaling or quiet),
+ /// the non-NaN input is returned.
///
/// The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0.
FMINNUM, FMAXNUM,
- /// FMINNAN/FMAXNAN - Behave identically to FMINNUM/FMAXNUM, except that
- /// when a single input is NaN, NaN is returned.
- FMINNAN, FMAXNAN,
+
+ /// FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on
+ /// two values, following the IEEE-754 2008 definition. This differs from
+ /// FMINNUM/FMAXNUM in the handling of signaling NaNs. If one input is a
+ /// signaling NaN, returns a quiet NaN.
+ FMINNUM_IEEE, FMAXNUM_IEEE,
+
+ /// FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0
+ /// as less than 0.0. While FMINNUM_IEEE/FMAXNUM_IEEE follow IEEE 754-2008
+ /// semantics, FMINIMUM/FMAXIMUM follow IEEE 754-2018 draft semantics.
+ FMINIMUM, FMAXIMUM,
/// FSINCOS - Compute both fsin and fcos as a single operation.
FSINCOS,
@@ -626,6 +667,9 @@
/// 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.
@@ -779,6 +823,8 @@
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
diff --git a/linux-x64/clang/include/llvm/CodeGen/IntrinsicLowering.h b/linux-x64/clang/include/llvm/CodeGen/IntrinsicLowering.h
index 597d684..daf2d9a 100644
--- a/linux-x64/clang/include/llvm/CodeGen/IntrinsicLowering.h
+++ b/linux-x64/clang/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 @@
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/linux-x64/clang/include/llvm/CodeGen/LatencyPriorityQueue.h b/linux-x64/clang/include/llvm/CodeGen/LatencyPriorityQueue.h
index 9b8d83c..95f4c64 100644
--- a/linux-x64/clang/include/llvm/CodeGen/LatencyPriorityQueue.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h b/linux-x64/clang/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h
index 221f16a..ca99c6c 100644
--- a/linux-x64/clang/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/LexicalScopes.h b/linux-x64/clang/include/llvm/CodeGen/LexicalScopes.h
index 3ba5034..253d473 100644
--- a/linux-x64/clang/include/llvm/CodeGen/LexicalScopes.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/LinkAllAsmWriterComponents.h b/linux-x64/clang/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
index c3046da..75a5c35 100644
--- a/linux-x64/clang/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -15,7 +14,7 @@
#ifndef LLVM_CODEGEN_LINKALLASMWRITERCOMPONENTS_H
#define LLVM_CODEGEN_LINKALLASMWRITERCOMPONENTS_H
-#include "llvm/CodeGen/GCs.h"
+#include "llvm/CodeGen/BuiltinGCs.h"
#include <cstdlib>
namespace {
diff --git a/linux-x64/clang/include/llvm/CodeGen/LinkAllCodegenComponents.h b/linux-x64/clang/include/llvm/CodeGen/LinkAllCodegenComponents.h
index fee131e..56c93b2 100644
--- a/linux-x64/clang/include/llvm/CodeGen/LinkAllCodegenComponents.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -15,7 +14,7 @@
#ifndef LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H
#define LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H
-#include "llvm/CodeGen/GCs.h"
+#include "llvm/CodeGen/BuiltinGCs.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/Target/TargetMachine.h"
@@ -36,11 +35,7 @@
(void) llvm::createGreedyRegisterAllocator();
(void) llvm::createDefaultPBQPRegisterAllocator();
- llvm::linkCoreCLRGC();
- llvm::linkOcamlGC();
- llvm::linkErlangGC();
- llvm::linkShadowStackGC();
- llvm::linkStatepointExampleGC();
+ llvm::linkAllBuiltinGCs();
(void) llvm::createBURRListDAGScheduler(nullptr,
llvm::CodeGenOpt::Default);
diff --git a/linux-x64/clang/include/llvm/CodeGen/LiveInterval.h b/linux-x64/clang/include/llvm/CodeGen/LiveInterval.h
index cdf9ad2..622c124 100644
--- a/linux-x64/clang/include/llvm/CodeGen/LiveInterval.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/LiveIntervalUnion.h b/linux-x64/clang/include/llvm/CodeGen/LiveIntervalUnion.h
index 9e2799b..05506d2 100644
--- a/linux-x64/clang/include/llvm/CodeGen/LiveIntervalUnion.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/LiveIntervals.h b/linux-x64/clang/include/llvm/CodeGen/LiveIntervals.h
index 291a07a..d0791be 100644
--- a/linux-x64/clang/include/llvm/CodeGen/LiveIntervals.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -198,10 +197,10 @@
void pruneValue(LiveRange &LR, SlotIndex Kill,
SmallVectorImpl<SlotIndex> *EndPoints);
- /// This function should not be used. Its intend is to tell you that
- /// you are doing something wrong if you call pruveValue directly on a
+ /// This function should not be used. Its intent is to tell you that you are
+ /// doing something wrong if you call pruneValue directly on a
/// LiveInterval. Indeed, you are supposed to call pruneValue on the main
- /// LiveRange and all the LiveRange of the subranges if any.
+ /// LiveRange and all the LiveRanges of the subranges if any.
LLVM_ATTRIBUTE_UNUSED void pruneValue(LiveInterval &, SlotIndex,
SmallVectorImpl<SlotIndex> *) {
llvm_unreachable(
diff --git a/linux-x64/clang/include/llvm/CodeGen/LivePhysRegs.h b/linux-x64/clang/include/llvm/CodeGen/LivePhysRegs.h
index 301a450..50da0b3 100644
--- a/linux-x64/clang/include/llvm/CodeGen/LivePhysRegs.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -48,7 +47,8 @@
/// when walking backward/forward through a basic block.
class LivePhysRegs {
const TargetRegisterInfo *TRI = nullptr;
- SparseSet<unsigned> LiveRegs;
+ using RegisterSet = SparseSet<MCPhysReg, identity<MCPhysReg>>;
+ RegisterSet LiveRegs;
public:
/// Constructs an unitialized set. init() needs to be called to initialize it.
@@ -76,7 +76,7 @@
bool empty() const { return LiveRegs.empty(); }
/// Adds a physical register and all its sub-registers to the set.
- void addReg(unsigned Reg) {
+ void addReg(MCPhysReg Reg) {
assert(TRI && "LivePhysRegs is not initialized.");
assert(Reg <= TRI->getNumRegs() && "Expected a physical register.");
for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
@@ -86,7 +86,7 @@
/// Removes a physical register, all its sub-registers, and all its
/// super-registers from the set.
- void removeReg(unsigned Reg) {
+ void removeReg(MCPhysReg Reg) {
assert(TRI && "LivePhysRegs is not initialized.");
assert(Reg <= TRI->getNumRegs() && "Expected a physical register.");
for (MCRegAliasIterator R(Reg, TRI, true); R.isValid(); ++R)
@@ -95,7 +95,7 @@
/// Removes physical registers clobbered by the regmask operand \p MO.
void removeRegsInMask(const MachineOperand &MO,
- SmallVectorImpl<std::pair<unsigned, const MachineOperand*>> *Clobbers =
+ SmallVectorImpl<std::pair<MCPhysReg, const MachineOperand*>> *Clobbers =
nullptr);
/// Returns true if register \p Reg is contained in the set. This also
@@ -103,10 +103,10 @@
/// addReg() always adds all sub-registers to the set as well.
/// Note: Returns false if just some sub registers are live, use available()
/// when searching a free register.
- bool contains(unsigned Reg) const { return LiveRegs.count(Reg); }
+ bool contains(MCPhysReg Reg) const { return LiveRegs.count(Reg); }
/// Returns true if register \p Reg and no aliasing register is in the set.
- bool available(const MachineRegisterInfo &MRI, unsigned Reg) const;
+ bool available(const MachineRegisterInfo &MRI, MCPhysReg Reg) const;
/// Remove defined registers and regmask kills from the set.
void removeDefs(const MachineInstr &MI);
@@ -126,7 +126,7 @@
/// defined or clobbered by a regmask. The operand will identify whether this
/// is a regmask or register operand.
void stepForward(const MachineInstr &MI,
- SmallVectorImpl<std::pair<unsigned, const MachineOperand*>> &Clobbers);
+ SmallVectorImpl<std::pair<MCPhysReg, const MachineOperand*>> &Clobbers);
/// Adds all live-in registers of basic block \p MBB.
/// Live in registers are the registers in the blocks live-in list and the
@@ -143,7 +143,7 @@
/// registers.
void addLiveOutsNoPristines(const MachineBasicBlock &MBB);
- using const_iterator = SparseSet<unsigned>::const_iterator;
+ using const_iterator = RegisterSet::const_iterator;
const_iterator begin() const { return LiveRegs.begin(); }
const_iterator end() const { return LiveRegs.end(); }
diff --git a/linux-x64/clang/include/llvm/CodeGen/LiveRangeEdit.h b/linux-x64/clang/include/llvm/CodeGen/LiveRangeEdit.h
index 5383029..6519937 100644
--- a/linux-x64/clang/include/llvm/CodeGen/LiveRangeEdit.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/LiveRegMatrix.h b/linux-x64/clang/include/llvm/CodeGen/LiveRegMatrix.h
index f62a55c..ab4d44f 100644
--- a/linux-x64/clang/include/llvm/CodeGen/LiveRegMatrix.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/LiveRegUnits.h b/linux-x64/clang/include/llvm/CodeGen/LiveRegUnits.h
index 2495459..7dbb2fe 100644
--- a/linux-x64/clang/include/llvm/CodeGen/LiveRegUnits.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -85,14 +84,14 @@
bool empty() const { return Units.none(); }
/// Adds register units covered by physical register \p Reg.
- void addReg(unsigned Reg) {
+ void addReg(MCPhysReg Reg) {
for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit)
Units.set(*Unit);
}
/// Adds register units covered by physical register \p Reg that are
/// part of the lanemask \p Mask.
- void addRegMasked(unsigned Reg, LaneBitmask Mask) {
+ void addRegMasked(MCPhysReg Reg, LaneBitmask Mask) {
for (MCRegUnitMaskIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) {
LaneBitmask UnitMask = (*Unit).second;
if (UnitMask.none() || (UnitMask & Mask).any())
@@ -101,7 +100,7 @@
}
/// Removes all register units covered by physical register \p Reg.
- void removeReg(unsigned Reg) {
+ void removeReg(MCPhysReg Reg) {
for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit)
Units.reset(*Unit);
}
@@ -115,7 +114,7 @@
void addRegsInMask(const uint32_t *RegMask);
/// Returns true if no part of physical register \p Reg is live.
- bool available(unsigned Reg) const {
+ bool available(MCPhysReg Reg) const {
for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) {
if (Units.test(*Unit))
return false;
diff --git a/linux-x64/clang/include/llvm/CodeGen/LiveStacks.h b/linux-x64/clang/include/llvm/CodeGen/LiveStacks.h
index 44ed785..7c4c64d 100644
--- a/linux-x64/clang/include/llvm/CodeGen/LiveStacks.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/LiveVariables.h b/linux-x64/clang/include/llvm/CodeGen/LiveVariables.h
index ed8da86..71de306 100644
--- a/linux-x64/clang/include/llvm/CodeGen/LiveVariables.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/LoopTraversal.h b/linux-x64/clang/include/llvm/CodeGen/LoopTraversal.h
index 750da01..e5810ef 100644
--- a/linux-x64/clang/include/llvm/CodeGen/LoopTraversal.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/LowLevelType.h b/linux-x64/clang/include/llvm/CodeGen/LowLevelType.h
index a3c5c93..687233e 100644
--- a/linux-x64/clang/include/llvm/CodeGen/LowLevelType.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MIRParser/MIRParser.h b/linux-x64/clang/include/llvm/CodeGen/MIRParser/MIRParser.h
index e199a1f..6a04e48 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MIRParser/MIRParser.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MIRPrinter.h b/linux-x64/clang/include/llvm/CodeGen/MIRPrinter.h
index 078c4b2..b95cf0f 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MIRPrinter.h
+++ b/linux-x64/clang/include/llvm/CodeGen/MIRPrinter.h
@@ -1,9 +1,8 @@
//===- MIRPrinter.h - MIR serialization format printer --------------------===//
//
-// 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/linux-x64/clang/include/llvm/CodeGen/MIRYamlMapping.h b/linux-x64/clang/include/llvm/CodeGen/MIRYamlMapping.h
index dc90575..b600ec9 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MIRYamlMapping.h
+++ b/linux-x64/clang/include/llvm/CodeGen/MIRYamlMapping.h
@@ -1,9 +1,8 @@
-//===- MIRYAMLMapping.h - Describes the mapping between MIR and YAML ------===//
+//===- MIRYamlMapping.h - Describes the mapping between MIR and YAML ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -494,6 +493,7 @@
bool FailedISel = false;
// Register information
bool TracksRegLiveness = false;
+ bool HasWinCFI = false;
std::vector<VirtualRegisterDefinition> VirtualRegisters;
std::vector<MachineFunctionLiveIn> LiveIns;
Optional<std::vector<FlowStringValue>> CalleeSavedRegisters;
@@ -517,6 +517,7 @@
YamlIO.mapOptional("selected", MF.Selected, false);
YamlIO.mapOptional("failedISel", MF.FailedISel, false);
YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness, false);
+ YamlIO.mapOptional("hasWinCFI", MF.HasWinCFI, false);
YamlIO.mapOptional("registers", MF.VirtualRegisters,
std::vector<VirtualRegisterDefinition>());
YamlIO.mapOptional("liveins", MF.LiveIns,
diff --git a/linux-x64/clang/include/llvm/CodeGen/MachORelocation.h b/linux-x64/clang/include/llvm/CodeGen/MachORelocation.h
index cbb4969..0185c7c 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachORelocation.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MachineBasicBlock.h b/linux-x64/clang/include/llvm/CodeGen/MachineBasicBlock.h
index ec2f270..34e18ba 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/MachineBlockFrequencyInfo.h b/linux-x64/clang/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
index 5b4b99c..a438ecf 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MachineBranchProbabilityInfo.h b/linux-x64/clang/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
index 81b0524..2b9b203 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MachineCombinerPattern.h b/linux-x64/clang/include/llvm/CodeGen/MachineCombinerPattern.h
index 586535f..4f4034b 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineCombinerPattern.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MachineConstantPool.h b/linux-x64/clang/include/llvm/CodeGen/MachineConstantPool.h
index b0b5420..4d07b62 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineConstantPool.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MachineDominanceFrontier.h b/linux-x64/clang/include/llvm/CodeGen/MachineDominanceFrontier.h
index 75d75bc..f7bbd07 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineDominanceFrontier.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MachineDominators.h b/linux-x64/clang/include/llvm/CodeGen/MachineDominators.h
index e3d3d16..d220008 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineDominators.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MachineFrameInfo.h b/linux-x64/clang/include/llvm/CodeGen/MachineFrameInfo.h
index 02b2f1b..402a2dc 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -28,9 +27,14 @@
/// The CalleeSavedInfo class tracks the information need to locate where a
/// callee saved register is in the current frame.
+/// Callee saved reg can also be saved to a different register rather than
+/// on the stack by setting DstReg instead of FrameIdx.
class CalleeSavedInfo {
unsigned Reg;
- int FrameIdx;
+ union {
+ int FrameIdx;
+ unsigned DstReg;
+ };
/// Flag indicating whether the register is actually restored in the epilog.
/// In most cases, if a register is saved, it is also restored. There are
/// some situations, though, when this is not the case. For example, the
@@ -44,17 +48,29 @@
/// by implicit uses on the return instructions, however, the required
/// changes in the ARM backend would be quite extensive.
bool Restored;
+ /// Flag indicating whether the register is spilled to stack or another
+ /// register.
+ bool SpilledToReg;
public:
explicit CalleeSavedInfo(unsigned R, int FI = 0)
- : Reg(R), FrameIdx(FI), Restored(true) {}
+ : Reg(R), FrameIdx(FI), Restored(true), SpilledToReg(false) {}
// Accessors.
unsigned getReg() const { return Reg; }
int getFrameIdx() const { return FrameIdx; }
- void setFrameIdx(int FI) { FrameIdx = FI; }
+ unsigned getDstReg() const { return DstReg; }
+ void setFrameIdx(int FI) {
+ FrameIdx = FI;
+ SpilledToReg = false;
+ }
+ void setDstReg(unsigned SpillReg) {
+ DstReg = SpillReg;
+ SpilledToReg = true;
+ }
bool isRestored() const { return Restored; }
void setRestored(bool R) { Restored = R; }
+ bool isSpilledToReg() const { return SpilledToReg; }
};
/// The MachineFrameInfo class represents an abstract stack frame until
@@ -271,9 +287,9 @@
unsigned CVBytesOfCalleeSavedRegisters = 0;
/// The prolog/epilog code inserter fills in this vector with each
- /// callee saved register saved in the frame. Beyond its use by the prolog/
- /// epilog code inserter, this data used for debug info and exception
- /// handling.
+ /// callee saved register saved in either the frame or a different
+ /// register. Beyond its use by the prolog/ epilog code inserter,
+ /// this data is used for debug info and exception handling.
std::vector<CalleeSavedInfo> CSInfo;
/// Has CSInfo been set yet?
diff --git a/linux-x64/clang/include/llvm/CodeGen/MachineFunction.h b/linux-x64/clang/include/llvm/CodeGen/MachineFunction.h
index 7471b31..34ceb15 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineFunction.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -58,6 +57,7 @@
class DILocation;
class Function;
class GlobalValue;
+class LLVMTargetMachine;
class MachineConstantPool;
class MachineFrameInfo;
class MachineFunction;
@@ -70,7 +70,6 @@
class PseudoSourceValueManager;
class raw_ostream;
class SlotIndexes;
-class TargetMachine;
class TargetRegisterClass;
class TargetSubtargetInfo;
struct WasmEHFuncInfo;
@@ -86,7 +85,7 @@
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");
}
};
@@ -225,7 +224,7 @@
class MachineFunction {
const Function &F;
- const TargetMachine &Target;
+ const LLVMTargetMachine &Target;
const TargetSubtargetInfo *STI;
MCContext &Ctx;
MachineModuleInfo &MMI;
@@ -316,6 +315,9 @@
/// Map a landing pad's EH symbol to the call site indexes.
DenseMap<MCSymbol*, SmallVector<unsigned, 4>> LPadToCallSiteMap;
+ /// Map a landing pad to its index.
+ DenseMap<const MachineBasicBlock *, unsigned> WasmLPadToIndexMap;
+
/// Map of invoke call site index values to associated begin EH_LABEL.
DenseMap<MCSymbol*, unsigned> CallSiteMap;
@@ -369,23 +371,25 @@
public:
virtual ~Delegate() = default;
- virtual void MF_HandleInsertion(const MachineInstr &MI) = 0;
- virtual void MF_HandleRemoval(const MachineInstr &MI) = 0;
+ /// Callback after an insertion. This should not modify the MI directly.
+ virtual void MF_HandleInsertion(MachineInstr &MI) = 0;
+ /// Callback before a removal. This should not modify the MI directly.
+ virtual void MF_HandleRemoval(MachineInstr &MI) = 0;
};
private:
Delegate *TheDelegate = nullptr;
// Callbacks for insertion and removal.
- void handleInsertion(const MachineInstr &MI);
- void handleRemoval(const MachineInstr &MI);
+ void handleInsertion(MachineInstr &MI);
+ void handleRemoval(MachineInstr &MI);
friend struct ilist_traits<MachineInstr>;
public:
using VariableDbgInfoMapTy = SmallVector<VariableDbgInfo, 4>;
VariableDbgInfoMapTy VariableDbgInfos;
- MachineFunction(const Function &F, const TargetMachine &Target,
+ MachineFunction(const Function &F, const LLVMTargetMachine &Target,
const TargetSubtargetInfo &STI, unsigned FunctionNum,
MachineModuleInfo &MMI);
MachineFunction(const MachineFunction &) = delete;
@@ -433,7 +437,7 @@
unsigned getFunctionNumber() const { return FunctionNumber; }
/// getTarget - Return the target machine this machine code is compiled with
- const TargetMachine &getTarget() const { return Target; }
+ const LLVMTargetMachine &getTarget() const { return Target; }
/// getSubtarget - Return the subtarget for which this machine code is being
/// compiled.
@@ -810,7 +814,8 @@
LandingPadInfo &getOrCreateLandingPadInfo(MachineBasicBlock *LandingPad);
/// Remap landing pad labels and remove any deleted landing pads.
- void tidyLandingPads(DenseMap<MCSymbol*, uintptr_t> *LPMap = nullptr);
+ void tidyLandingPads(DenseMap<MCSymbol *, uintptr_t> *LPMap = nullptr,
+ bool TidyIfNoBeginLabels = true);
/// Return a reference to the landing pad info for the current function.
const std::vector<LandingPadInfo> &getLandingPads() const {
@@ -853,6 +858,22 @@
/// Map the landing pad's EH symbol to the call site indexes.
void setCallSiteLandingPad(MCSymbol *Sym, ArrayRef<unsigned> Sites);
+ /// Map the landing pad to its index. Used for Wasm exception handling.
+ void setWasmLandingPadIndex(const MachineBasicBlock *LPad, unsigned Index) {
+ WasmLPadToIndexMap[LPad] = Index;
+ }
+
+ /// Returns true if the landing pad has an associate index in wasm EH.
+ bool hasWasmLandingPadIndex(const MachineBasicBlock *LPad) const {
+ return WasmLPadToIndexMap.count(LPad);
+ }
+
+ /// Get the index in wasm EH for a given landing pad.
+ unsigned getWasmLandingPadIndex(const MachineBasicBlock *LPad) const {
+ assert(hasWasmLandingPadIndex(LPad));
+ return WasmLPadToIndexMap.lookup(LPad);
+ }
+
/// Get the call site indexes for a landing pad EH symbol.
SmallVectorImpl<unsigned> &getCallSiteLandingPad(MCSymbol *Sym) {
assert(hasCallSiteLandingPad(Sym) &&
diff --git a/linux-x64/clang/include/llvm/CodeGen/MachineFunctionPass.h b/linux-x64/clang/include/llvm/CodeGen/MachineFunctionPass.h
index 6d978da..caaf22c 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineFunctionPass.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MachineInstr.h b/linux-x64/clang/include/llvm/CodeGen/MachineInstr.h
index 7c4e771..4cb39c5 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineInstr.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -408,7 +407,7 @@
/// Returns the opcode of this MachineInstr.
unsigned getOpcode() const { return MCID->Opcode; }
- /// Access to explicit operands of the instruction.
+ /// Retuns the total number of operands.
unsigned getNumOperands() const { return NumOperands; }
const MachineOperand& getOperand(unsigned i) const {
@@ -1012,10 +1011,13 @@
}
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;
+ }
bool isMSInlineAsm() const {
- return getOpcode() == TargetOpcode::INLINEASM && getInlineAsmDialect();
+ return isInlineAsm() && getInlineAsmDialect() == InlineAsm::AD_Intel;
}
bool isStackAligningInlineAsm() const;
@@ -1400,6 +1402,19 @@
/// 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);
@@ -1526,6 +1541,8 @@
/// 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/linux-x64/clang/include/llvm/CodeGen/MachineInstrBuilder.h b/linux-x64/clang/include/llvm/CodeGen/MachineInstrBuilder.h
index b5e523f..4a8cd68 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/linux-x64/clang/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 @@
/// 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).
+ unsigned getReg(unsigned Idx) { return MI->getOperand(Idx).getReg(); }
+
/// Add a new virtual register operand.
const MachineInstrBuilder &addReg(unsigned RegNo, unsigned flags = 0,
unsigned SubReg = 0) const {
diff --git a/linux-x64/clang/include/llvm/CodeGen/MachineInstrBundle.h b/linux-x64/clang/include/llvm/CodeGen/MachineInstrBundle.h
index b5341fd..9bb5b63 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineInstrBundle.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/MachineInstrBundleIterator.h b/linux-x64/clang/include/llvm/CodeGen/MachineInstrBundleIterator.h
index 5fe4964..0f59563 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineInstrBundleIterator.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MachineJumpTableInfo.h b/linux-x64/clang/include/llvm/CodeGen/MachineJumpTableInfo.h
index 25a3e6b..1178114 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineJumpTableInfo.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MachineLoopInfo.h b/linux-x64/clang/include/llvm/CodeGen/MachineLoopInfo.h
index 917fb90..da6df59 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineLoopInfo.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MachineMemOperand.h b/linux-x64/clang/include/llvm/CodeGen/MachineMemOperand.h
index 078ef7c..12fae2f 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineMemOperand.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -267,13 +266,13 @@
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/linux-x64/clang/include/llvm/CodeGen/MachineModuleInfo.h b/linux-x64/clang/include/llvm/CodeGen/MachineModuleInfo.h
index 554e890..9b81dc6 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -46,10 +45,10 @@
class BasicBlock;
class CallInst;
class Function;
-class MachineFunction;
+class LLVMTargetMachine;
class MMIAddrLabelMap;
+class MachineFunction;
class Module;
-class TargetMachine;
//===----------------------------------------------------------------------===//
/// This class can be derived from and used by targets to hold private
@@ -76,7 +75,7 @@
/// for specific use.
///
class MachineModuleInfo : public ImmutablePass {
- const TargetMachine &TM;
+ const LLVMTargetMachine &TM;
/// This is the MCContext used for the entire code generator.
MCContext Context;
@@ -114,10 +113,9 @@
/// 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
@@ -145,7 +143,7 @@
public:
static char ID; // Pass identification, replacement for typeid
- explicit MachineModuleInfo(const TargetMachine *TM = nullptr);
+ explicit MachineModuleInfo(const LLVMTargetMachine *TM = nullptr);
~MachineModuleInfo() override;
// Initialization and Finalization
@@ -187,13 +185,9 @@
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 +252,6 @@
/// \}
}; // 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/linux-x64/clang/include/llvm/CodeGen/MachineModuleInfoImpls.h b/linux-x64/clang/include/llvm/CodeGen/MachineModuleInfoImpls.h
index 17df1fa..746e922 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineModuleInfoImpls.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MachineOperand.h b/linux-x64/clang/include/llvm/CodeGen/MachineOperand.h
index 53e8889..ddcdc07 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineOperand.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h b/linux-x64/clang/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
index a7ce870..9a0fd56 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
+++ b/linux-x64/clang/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
diff --git a/linux-x64/clang/include/llvm/CodeGen/MachineOutliner.h b/linux-x64/clang/include/llvm/CodeGen/MachineOutliner.h
index 95bfc24..377df4e 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineOutliner.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
///
@@ -61,9 +60,6 @@
/// \p OutlinedFunctions.
unsigned FunctionIdx;
- /// Set to false if the candidate overlapped with another candidate.
- bool InCandidateList = true;
-
/// Identifier denoting the instructions to emit to call an outlined function
/// from this point. Defined by the target.
unsigned CallConstructionID;
@@ -82,6 +78,12 @@
/// been used across the sequence.
LiveRegUnits UsedInSequence;
+ /// Target-specific flags for this Candidate's MBB.
+ unsigned Flags = 0x0;
+
+ /// True if initLRU has been called on this Candidate.
+ bool LRUWasSet = false;
+
/// Return the number of instructions in this Candidate.
unsigned getLength() const { return Len; }
@@ -99,9 +101,7 @@
}
/// Returns the call overhead of this candidate if it is in the list.
- unsigned getCallOverhead() const {
- return InCandidateList ? CallOverhead : 0;
- }
+ unsigned getCallOverhead() const { return CallOverhead; }
MachineBasicBlock::iterator &front() { return FirstInst; }
MachineBasicBlock::iterator &back() { return LastInst; }
@@ -120,9 +120,9 @@
Candidate(unsigned StartIdx, unsigned Len,
MachineBasicBlock::iterator &FirstInst,
MachineBasicBlock::iterator &LastInst, MachineBasicBlock *MBB,
- unsigned FunctionIdx)
+ unsigned FunctionIdx, unsigned Flags)
: StartIdx(StartIdx), Len(Len), FirstInst(FirstInst), LastInst(LastInst),
- MBB(MBB), FunctionIdx(FunctionIdx) {}
+ MBB(MBB), FunctionIdx(FunctionIdx), Flags(Flags) {}
Candidate() {}
/// Used to ensure that \p Candidates are outlined in an order that
@@ -138,6 +138,10 @@
void initLRU(const TargetRegisterInfo &TRI) {
assert(MBB->getParent()->getRegInfo().tracksLiveness() &&
"Candidate's Machine Function must track liveness");
+ // Only initialize once.
+ if (LRUWasSet)
+ return;
+ LRUWasSet = true;
LRU.init(TRI);
LRU.addLiveOuts(*MBB);
@@ -158,24 +162,13 @@
/// class of candidate.
struct OutlinedFunction {
-private:
- /// The number of candidates for this \p OutlinedFunction.
- unsigned OccurrenceCount = 0;
-
public:
- std::vector<std::shared_ptr<Candidate>> Candidates;
+ std::vector<Candidate> Candidates;
/// The actual outlined function created.
/// This is initialized after we go through and create the actual function.
MachineFunction *MF = nullptr;
- /// A number assigned to this function which appears at the end of its name.
- unsigned Name;
-
- /// The sequence of integers corresponding to the instructions in this
- /// function.
- std::vector<unsigned> Sequence;
-
/// 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;
@@ -187,49 +180,41 @@
unsigned FrameConstructionID;
/// Return the number of candidates for this \p OutlinedFunction.
- unsigned getOccurrenceCount() { return OccurrenceCount; }
-
- /// Decrement the occurrence count of this OutlinedFunction and return the
- /// new count.
- unsigned decrement() {
- assert(OccurrenceCount > 0 && "Can't decrement an empty function!");
- OccurrenceCount--;
- return getOccurrenceCount();
- }
+ unsigned getOccurrenceCount() const { return Candidates.size(); }
/// Return the number of bytes it would take to outline this
/// function.
- unsigned getOutliningCost() {
+ unsigned getOutliningCost() const {
unsigned CallOverhead = 0;
- for (std::shared_ptr<Candidate> &C : Candidates)
- CallOverhead += C->getCallOverhead();
+ for (const Candidate &C : Candidates)
+ CallOverhead += C.getCallOverhead();
return CallOverhead + SequenceSize + FrameOverhead;
}
/// Return the size in bytes of the unoutlined sequences.
- unsigned getNotOutlinedCost() { return OccurrenceCount * SequenceSize; }
+ unsigned getNotOutlinedCost() const {
+ return getOccurrenceCount() * SequenceSize;
+ }
/// Return the number of instructions that would be saved by outlining
/// this function.
- unsigned getBenefit() {
+ unsigned getBenefit() const {
unsigned NotOutlinedCost = getNotOutlinedCost();
unsigned OutlinedCost = getOutliningCost();
return (NotOutlinedCost < OutlinedCost) ? 0
: NotOutlinedCost - OutlinedCost;
}
- OutlinedFunction(std::vector<Candidate> &Cands,
- unsigned SequenceSize, unsigned FrameOverhead,
- unsigned FrameConstructionID)
- : SequenceSize(SequenceSize), FrameOverhead(FrameOverhead),
- FrameConstructionID(FrameConstructionID) {
- OccurrenceCount = Cands.size();
- for (Candidate &C : Cands)
- Candidates.push_back(std::make_shared<outliner::Candidate>(C));
+ /// Return the number of instructions in this sequence.
+ unsigned getNumInstrs() const { return Candidates[0].getLength(); }
- unsigned B = getBenefit();
- for (std::shared_ptr<Candidate> &C : Candidates)
- C->Benefit = B;
+ OutlinedFunction(std::vector<Candidate> &Candidates, unsigned SequenceSize,
+ unsigned FrameOverhead, unsigned FrameConstructionID)
+ : Candidates(Candidates), SequenceSize(SequenceSize),
+ FrameOverhead(FrameOverhead), FrameConstructionID(FrameConstructionID) {
+ const unsigned B = getBenefit();
+ for (Candidate &C : Candidates)
+ C.Benefit = B;
}
OutlinedFunction() {}
diff --git a/linux-x64/clang/include/llvm/CodeGen/MachinePassRegistry.h b/linux-x64/clang/include/llvm/CodeGen/MachinePassRegistry.h
index 3aba0bb..f5b3723 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachinePassRegistry.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -24,22 +23,20 @@
namespace llvm {
-using MachinePassCtor = void *(*)();
-
//===----------------------------------------------------------------------===//
///
/// MachinePassRegistryListener - Listener to adds and removals of nodes in
/// registration list.
///
//===----------------------------------------------------------------------===//
-class MachinePassRegistryListener {
- virtual void anchor();
+template <class PassCtorTy> class MachinePassRegistryListener {
+ virtual void anchor() {}
public:
MachinePassRegistryListener() = default;
virtual ~MachinePassRegistryListener() = default;
- virtual void NotifyAdd(StringRef N, MachinePassCtor C, StringRef D) = 0;
+ virtual void NotifyAdd(StringRef N, PassCtorTy C, StringRef D) = 0;
virtual void NotifyRemove(StringRef N) = 0;
};
@@ -48,15 +45,15 @@
/// MachinePassRegistryNode - Machine pass node stored in registration list.
///
//===----------------------------------------------------------------------===//
-class MachinePassRegistryNode {
+template <typename PassCtorTy> class MachinePassRegistryNode {
private:
MachinePassRegistryNode *Next = nullptr; // Next function pass in list.
StringRef Name; // Name of function pass.
StringRef Description; // Description string.
- MachinePassCtor Ctor; // Function pass creator.
+ PassCtorTy Ctor; // Pass creator.
public:
- MachinePassRegistryNode(const char *N, const char *D, MachinePassCtor C)
+ MachinePassRegistryNode(const char *N, const char *D, PassCtorTy C)
: Name(N), Description(D), Ctor(C) {}
// Accessors
@@ -64,7 +61,7 @@
MachinePassRegistryNode **getNextAddress() { return &Next; }
StringRef getName() const { return Name; }
StringRef getDescription() const { return Description; }
- MachinePassCtor getCtor() const { return Ctor; }
+ PassCtorTy getCtor() const { return Ctor; }
void setNext(MachinePassRegistryNode *N) { Next = N; }
};
@@ -73,11 +70,12 @@
/// MachinePassRegistry - Track the registration of machine passes.
///
//===----------------------------------------------------------------------===//
-class MachinePassRegistry {
+template <typename PassCtorTy> class MachinePassRegistry {
private:
- MachinePassRegistryNode *List; // List of registry nodes.
- MachinePassCtor Default; // Default function pass creator.
- MachinePassRegistryListener *Listener; // Listener for list adds are removes.
+ MachinePassRegistryNode<PassCtorTy> *List; // List of registry nodes.
+ PassCtorTy Default; // Default function pass creator.
+ MachinePassRegistryListener<PassCtorTy>
+ *Listener; // Listener for list adds are removes.
public:
// NO CONSTRUCTOR - we don't want static constructor ordering to mess
@@ -85,19 +83,47 @@
// Accessors.
//
- MachinePassRegistryNode *getList() { return List; }
- MachinePassCtor getDefault() { return Default; }
- void setDefault(MachinePassCtor C) { Default = C; }
- void setDefault(StringRef Name);
- void setListener(MachinePassRegistryListener *L) { Listener = L; }
+ MachinePassRegistryNode<PassCtorTy> *getList() { return List; }
+ PassCtorTy getDefault() { return Default; }
+ void setDefault(PassCtorTy C) { Default = C; }
+ /// setDefault - Set the default constructor by name.
+ void setDefault(StringRef Name) {
+ PassCtorTy Ctor = nullptr;
+ for (MachinePassRegistryNode<PassCtorTy> *R = getList(); R;
+ R = R->getNext()) {
+ if (R->getName() == Name) {
+ Ctor = R->getCtor();
+ break;
+ }
+ }
+ assert(Ctor && "Unregistered pass name");
+ setDefault(Ctor);
+ }
+ void setListener(MachinePassRegistryListener<PassCtorTy> *L) { Listener = L; }
/// Add - Adds a function pass to the registration list.
///
- void Add(MachinePassRegistryNode *Node);
+ void Add(MachinePassRegistryNode<PassCtorTy> *Node) {
+ Node->setNext(List);
+ List = Node;
+ if (Listener)
+ Listener->NotifyAdd(Node->getName(), Node->getCtor(),
+ Node->getDescription());
+ }
/// Remove - Removes a function pass from the registration list.
///
- void Remove(MachinePassRegistryNode *Node);
+ void Remove(MachinePassRegistryNode<PassCtorTy> *Node) {
+ for (MachinePassRegistryNode<PassCtorTy> **I = &List; *I;
+ I = (*I)->getNextAddress()) {
+ if (*I == Node) {
+ if (Listener)
+ Listener->NotifyRemove(Node->getName());
+ *I = (*I)->getNext();
+ break;
+ }
+ }
+ }
};
//===----------------------------------------------------------------------===//
@@ -105,9 +131,11 @@
/// RegisterPassParser class - Handle the addition of new machine passes.
///
//===----------------------------------------------------------------------===//
-template<class RegistryClass>
-class RegisterPassParser : public MachinePassRegistryListener,
- public cl::parser<typename RegistryClass::FunctionPassCtor> {
+template <class RegistryClass>
+class RegisterPassParser
+ : public MachinePassRegistryListener<
+ typename RegistryClass::FunctionPassCtor>,
+ public cl::parser<typename RegistryClass::FunctionPassCtor> {
public:
RegisterPassParser(cl::Option &O)
: cl::parser<typename RegistryClass::FunctionPassCtor>(O) {}
@@ -129,8 +157,9 @@
}
// Implement the MachinePassRegistryListener callbacks.
- void NotifyAdd(StringRef N, MachinePassCtor C, StringRef D) override {
- this->addLiteralOption(N, (typename RegistryClass::FunctionPassCtor)C, D);
+ void NotifyAdd(StringRef N, typename RegistryClass::FunctionPassCtor C,
+ StringRef D) override {
+ this->addLiteralOption(N, C, D);
}
void NotifyRemove(StringRef N) override {
this->removeLiteralOption(N);
diff --git a/linux-x64/clang/include/llvm/CodeGen/MachinePipeliner.h b/linux-x64/clang/include/llvm/CodeGen/MachinePipeliner.h
new file mode 100644
index 0000000..a30e4b9
--- /dev/null
+++ b/linux-x64/clang/include/llvm/CodeGen/MachinePipeliner.h
@@ -0,0 +1,614 @@
+//===- MachinePipeliner.h - Machine Software Pipeliner Pass -------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// An implementation of the Swing Modulo Scheduling (SMS) software pipeliner.
+//
+// Software pipelining (SWP) is an instruction scheduling technique for loops
+// that overlap loop iterations and exploits ILP via a compiler transformation.
+//
+// Swing Modulo Scheduling is an implementation of software pipelining
+// that generates schedules that are near optimal in terms of initiation
+// interval, register requirements, and stage count. See the papers:
+//
+// "Swing Modulo Scheduling: A Lifetime-Sensitive Approach", by J. Llosa,
+// A. Gonzalez, E. Ayguade, and M. Valero. In PACT '96 Proceedings of the 1996
+// Conference on Parallel Architectures and Compilation Techiniques.
+//
+// "Lifetime-Sensitive Modulo Scheduling in a Production Environment", by J.
+// Llosa, E. Ayguade, A. Gonzalez, M. Valero, and J. Eckhardt. In IEEE
+// Transactions on Computers, Vol. 50, No. 3, 2001.
+//
+// "An Implementation of Swing Modulo Scheduling With Extensions for
+// Superblocks", by T. Lattner, Master's Thesis, University of Illinois at
+// Urbana-Champaign, 2005.
+//
+//
+// The SMS algorithm consists of three main steps after computing the minimal
+// initiation interval (MII).
+// 1) Analyze the dependence graph and compute information about each
+// instruction in the graph.
+// 2) Order the nodes (instructions) by priority based upon the heuristics
+// described in the algorithm.
+// 3) Attempt to schedule the nodes in the specified order using the MII.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIB_CODEGEN_MACHINEPIPELINER_H
+#define LLVM_LIB_CODEGEN_MACHINEPIPELINER_H
+
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/RegisterClassInfo.h"
+#include "llvm/CodeGen/ScheduleDAGInstrs.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+
+namespace llvm {
+
+class NodeSet;
+class SMSchedule;
+
+extern cl::opt<bool> SwpEnableCopyToPhi;
+
+/// The main class in the implementation of the target independent
+/// software pipeliner pass.
+class MachinePipeliner : public MachineFunctionPass {
+public:
+ MachineFunction *MF = nullptr;
+ const MachineLoopInfo *MLI = nullptr;
+ const MachineDominatorTree *MDT = nullptr;
+ const InstrItineraryData *InstrItins;
+ const TargetInstrInfo *TII = nullptr;
+ RegisterClassInfo RegClassInfo;
+ bool disabledByPragma = false;
+ unsigned II_setByPragma = 0;
+
+#ifndef NDEBUG
+ static int NumTries;
+#endif
+
+ /// Cache the target analysis information about the loop.
+ struct LoopInfo {
+ MachineBasicBlock *TBB = nullptr;
+ MachineBasicBlock *FBB = nullptr;
+ SmallVector<MachineOperand, 4> BrCond;
+ MachineInstr *LoopInductionVar = nullptr;
+ MachineInstr *LoopCompare = nullptr;
+ };
+ LoopInfo LI;
+
+ static char ID;
+
+ MachinePipeliner() : MachineFunctionPass(ID) {
+ initializeMachinePipelinerPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<AAResultsWrapperPass>();
+ AU.addPreserved<AAResultsWrapperPass>();
+ AU.addRequired<MachineLoopInfo>();
+ AU.addRequired<MachineDominatorTree>();
+ AU.addRequired<LiveIntervals>();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+private:
+ void preprocessPhiNodes(MachineBasicBlock &B);
+ 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,
+/// and attempts to schedule the instructions using the SMS algorithm.
+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.
+ ScheduleDAGTopologicalSort Topo;
+
+ struct NodeInfo {
+ int ASAP = 0;
+ int ALAP = 0;
+ int ZeroLatencyDepth = 0;
+ int ZeroLatencyHeight = 0;
+
+ NodeInfo() = default;
+ };
+ /// Computed properties for each node in the graph.
+ std::vector<NodeInfo> ScheduleInfo;
+
+ enum OrderKind { BottomUp = 0, TopDown = 1 };
+ /// Computed node ordering for scheduling.
+ SetVector<SUnit *> NodeOrder;
+
+ using NodeSetType = SmallVector<NodeSet, 8>;
+ using ValueMapTy = DenseMap<unsigned, unsigned>;
+ using MBBVectorTy = SmallVectorImpl<MachineBasicBlock *>;
+ using InstrMapTy = DenseMap<MachineInstr *, MachineInstr *>;
+
+ /// Instructions to change when emitting the final schedule.
+ DenseMap<SUnit *, std::pair<unsigned, int64_t>> InstrChanges;
+
+ /// We may create a new instruction, so remember it because it
+ /// must be deleted when the pass is finished.
+ SmallPtrSet<MachineInstr *, 4> NewMIs;
+
+ /// Ordered list of DAG postprocessing steps.
+ std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
+
+ /// Helper class to implement Johnson's circuit finding algorithm.
+ class Circuits {
+ std::vector<SUnit> &SUnits;
+ SetVector<SUnit *> Stack;
+ BitVector Blocked;
+ SmallVector<SmallPtrSet<SUnit *, 4>, 10> B;
+ SmallVector<SmallVector<int, 4>, 16> AdjK;
+ // Node to Index from ScheduleDAGTopologicalSort
+ std::vector<int> *Node2Idx;
+ unsigned NumPaths;
+ static unsigned MaxPaths;
+
+ public:
+ Circuits(std::vector<SUnit> &SUs, ScheduleDAGTopologicalSort &Topo)
+ : SUnits(SUs), Blocked(SUs.size()), B(SUs.size()), AdjK(SUs.size()) {
+ Node2Idx = new std::vector<int>(SUs.size());
+ unsigned Idx = 0;
+ for (const auto &NodeNum : Topo)
+ Node2Idx->at(NodeNum) = Idx++;
+ }
+
+ ~Circuits() { delete Node2Idx; }
+
+ /// Reset the data structures used in the circuit algorithm.
+ void reset() {
+ Stack.clear();
+ Blocked.reset();
+ B.assign(SUnits.size(), SmallPtrSet<SUnit *, 4>());
+ NumPaths = 0;
+ }
+
+ void createAdjacencyStructure(SwingSchedulerDAG *DAG);
+ bool circuit(int V, int S, NodeSetType &NodeSets, bool HasBackedge = false);
+ void unblock(int U);
+ };
+
+ struct CopyToPhiMutation : public ScheduleDAGMutation {
+ void apply(ScheduleDAGInstrs *DAG) override;
+ };
+
+public:
+ SwingSchedulerDAG(MachinePipeliner &P, MachineLoop &L, LiveIntervals &lis,
+ const RegisterClassInfo &rci, unsigned II)
+ : ScheduleDAGInstrs(*P.MF, P.MLI, false), Pass(P), Loop(L), LIS(lis),
+ RegClassInfo(rci), II_setByPragma(II), Topo(SUnits, &ExitSU) {
+ P.MF->getSubtarget().getSMSMutations(Mutations);
+ if (SwpEnableCopyToPhi)
+ Mutations.push_back(llvm::make_unique<CopyToPhiMutation>());
+ }
+
+ void schedule() override;
+ void finishBlock() override;
+
+ /// Return true if the loop kernel has been scheduled.
+ bool hasNewSchedule() { return Scheduled; }
+
+ /// Return the earliest time an instruction may be scheduled.
+ int getASAP(SUnit *Node) { return ScheduleInfo[Node->NodeNum].ASAP; }
+
+ /// Return the latest time an instruction my be scheduled.
+ int getALAP(SUnit *Node) { return ScheduleInfo[Node->NodeNum].ALAP; }
+
+ /// The mobility function, which the number of slots in which
+ /// an instruction may be scheduled.
+ int getMOV(SUnit *Node) { return getALAP(Node) - getASAP(Node); }
+
+ /// The depth, in the dependence graph, for a node.
+ unsigned getDepth(SUnit *Node) { return Node->getDepth(); }
+
+ /// The maximum unweighted length of a path from an arbitrary node to the
+ /// given node in which each edge has latency 0
+ int getZeroLatencyDepth(SUnit *Node) {
+ return ScheduleInfo[Node->NodeNum].ZeroLatencyDepth;
+ }
+
+ /// The height, in the dependence graph, for a node.
+ unsigned getHeight(SUnit *Node) { return Node->getHeight(); }
+
+ /// The maximum unweighted length of a path from the given node to an
+ /// arbitrary node in which each edge has latency 0
+ int getZeroLatencyHeight(SUnit *Node) {
+ return ScheduleInfo[Node->NodeNum].ZeroLatencyHeight;
+ }
+
+ /// Return true if the dependence is a back-edge in the data dependence graph.
+ /// Since the DAG doesn't contain cycles, we represent a cycle in the graph
+ /// using an anti dependence from a Phi to an instruction.
+ bool isBackedge(SUnit *Source, const SDep &Dep) {
+ if (Dep.getKind() != SDep::Anti)
+ return false;
+ return Source->getInstr()->isPHI() || Dep.getSUnit()->getInstr()->isPHI();
+ }
+
+ bool isLoopCarriedDep(SUnit *Source, const SDep &Dep, bool isSucc = true);
+
+ /// The distance function, which indicates that operation V of iteration I
+ /// depends on operations U of iteration I-distance.
+ unsigned getDistance(SUnit *U, SUnit *V, const SDep &Dep) {
+ // Instructions that feed a Phi have a distance of 1. Computing larger
+ // values for arrays requires data dependence information.
+ if (V->getInstr()->isPHI() && Dep.getKind() == SDep::Anti)
+ return 1;
+ return 0;
+ }
+
+ void applyInstrChange(MachineInstr *MI, SMSchedule &Schedule);
+
+ void fixupRegisterOverlaps(std::deque<SUnit *> &Instrs);
+
+ /// Return the new base register that was stored away for the changed
+ /// instruction.
+ unsigned getInstrBaseReg(SUnit *SU) {
+ DenseMap<SUnit *, std::pair<unsigned, int64_t>>::iterator It =
+ InstrChanges.find(SU);
+ if (It != InstrChanges.end())
+ return It->second.first;
+ return 0;
+ }
+
+ void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation) {
+ Mutations.push_back(std::move(Mutation));
+ }
+
+ static bool classof(const ScheduleDAGInstrs *DAG) { return true; }
+
+private:
+ void addLoopCarriedDependences(AliasAnalysis *AA);
+ void updatePhiDependences();
+ void changeDependences();
+ unsigned calculateResMII();
+ unsigned calculateRecMII(NodeSetType &RecNodeSets);
+ void findCircuits(NodeSetType &NodeSets);
+ void fuseRecs(NodeSetType &NodeSets);
+ void removeDuplicateNodes(NodeSetType &NodeSets);
+ void computeNodeFunctions(NodeSetType &NodeSets);
+ void registerPressureFilter(NodeSetType &NodeSets);
+ void colocateNodeSets(NodeSetType &NodeSets);
+ void checkNodeSets(NodeSetType &NodeSets);
+ void groupRemainingNodes(NodeSetType &NodeSets);
+ void addConnectedNodes(SUnit *SU, NodeSet &NewSet,
+ SetVector<SUnit *> &NodesAdded);
+ void computeNodeOrder(NodeSetType &NodeSets);
+ void checkValidNodeOrder(const NodeSetType &Circuits) const;
+ bool schedulePipeline(SMSchedule &Schedule);
+ void generatePipelinedLoop(SMSchedule &Schedule);
+ void generateProlog(SMSchedule &Schedule, unsigned LastStage,
+ MachineBasicBlock *KernelBB, ValueMapTy *VRMap,
+ MBBVectorTy &PrologBBs);
+ void generateEpilog(SMSchedule &Schedule, unsigned LastStage,
+ MachineBasicBlock *KernelBB, ValueMapTy *VRMap,
+ MBBVectorTy &EpilogBBs, MBBVectorTy &PrologBBs);
+ void generateExistingPhis(MachineBasicBlock *NewBB, MachineBasicBlock *BB1,
+ MachineBasicBlock *BB2, MachineBasicBlock *KernelBB,
+ SMSchedule &Schedule, ValueMapTy *VRMap,
+ InstrMapTy &InstrMap, unsigned LastStageNum,
+ unsigned CurStageNum, bool IsLast);
+ void generatePhis(MachineBasicBlock *NewBB, MachineBasicBlock *BB1,
+ MachineBasicBlock *BB2, MachineBasicBlock *KernelBB,
+ SMSchedule &Schedule, ValueMapTy *VRMap,
+ InstrMapTy &InstrMap, unsigned LastStageNum,
+ unsigned CurStageNum, bool IsLast);
+ void removeDeadInstructions(MachineBasicBlock *KernelBB,
+ MBBVectorTy &EpilogBBs);
+ void splitLifetimes(MachineBasicBlock *KernelBB, MBBVectorTy &EpilogBBs,
+ SMSchedule &Schedule);
+ void addBranches(MBBVectorTy &PrologBBs, MachineBasicBlock *KernelBB,
+ MBBVectorTy &EpilogBBs, SMSchedule &Schedule,
+ ValueMapTy *VRMap);
+ bool computeDelta(MachineInstr &MI, unsigned &Delta);
+ void updateMemOperands(MachineInstr &NewMI, MachineInstr &OldMI,
+ unsigned Num);
+ MachineInstr *cloneInstr(MachineInstr *OldMI, unsigned CurStageNum,
+ unsigned InstStageNum);
+ MachineInstr *cloneAndChangeInstr(MachineInstr *OldMI, unsigned CurStageNum,
+ unsigned InstStageNum,
+ SMSchedule &Schedule);
+ void updateInstruction(MachineInstr *NewMI, bool LastDef,
+ unsigned CurStageNum, unsigned InstrStageNum,
+ SMSchedule &Schedule, ValueMapTy *VRMap);
+ MachineInstr *findDefInLoop(unsigned Reg);
+ unsigned getPrevMapVal(unsigned StageNum, unsigned PhiStage, unsigned LoopVal,
+ unsigned LoopStage, ValueMapTy *VRMap,
+ MachineBasicBlock *BB);
+ void rewritePhiValues(MachineBasicBlock *NewBB, unsigned StageNum,
+ SMSchedule &Schedule, ValueMapTy *VRMap,
+ InstrMapTy &InstrMap);
+ void rewriteScheduledInstr(MachineBasicBlock *BB, SMSchedule &Schedule,
+ InstrMapTy &InstrMap, unsigned CurStageNum,
+ unsigned PhiNum, MachineInstr *Phi,
+ unsigned OldReg, unsigned NewReg,
+ unsigned PrevReg = 0);
+ bool canUseLastOffsetValue(MachineInstr *MI, unsigned &BasePos,
+ 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
+/// that assigns a priority to the set.
+class NodeSet {
+ SetVector<SUnit *> Nodes;
+ bool HasRecurrence = false;
+ unsigned RecMII = 0;
+ int MaxMOV = 0;
+ unsigned MaxDepth = 0;
+ unsigned Colocate = 0;
+ SUnit *ExceedPressure = nullptr;
+ unsigned Latency = 0;
+
+public:
+ using iterator = SetVector<SUnit *>::const_iterator;
+
+ NodeSet() = default;
+ NodeSet(iterator S, iterator E) : Nodes(S, E), HasRecurrence(true) {
+ Latency = 0;
+ for (unsigned i = 0, e = Nodes.size(); i < e; ++i)
+ for (const SDep &Succ : Nodes[i]->Succs)
+ if (Nodes.count(Succ.getSUnit()))
+ Latency += Succ.getLatency();
+ }
+
+ bool insert(SUnit *SU) { return Nodes.insert(SU); }
+
+ void insert(iterator S, iterator E) { Nodes.insert(S, E); }
+
+ template <typename UnaryPredicate> bool remove_if(UnaryPredicate P) {
+ return Nodes.remove_if(P);
+ }
+
+ unsigned count(SUnit *SU) const { return Nodes.count(SU); }
+
+ bool hasRecurrence() { return HasRecurrence; };
+
+ unsigned size() const { return Nodes.size(); }
+
+ bool empty() const { return Nodes.empty(); }
+
+ SUnit *getNode(unsigned i) const { return Nodes[i]; };
+
+ void setRecMII(unsigned mii) { RecMII = mii; };
+
+ void setColocate(unsigned c) { Colocate = c; };
+
+ void setExceedPressure(SUnit *SU) { ExceedPressure = SU; }
+
+ bool isExceedSU(SUnit *SU) { return ExceedPressure == SU; }
+
+ int compareRecMII(NodeSet &RHS) { return RecMII - RHS.RecMII; }
+
+ int getRecMII() { return RecMII; }
+
+ /// Summarize node functions for the entire node set.
+ void computeNodeSetInfo(SwingSchedulerDAG *SSD) {
+ for (SUnit *SU : *this) {
+ MaxMOV = std::max(MaxMOV, SSD->getMOV(SU));
+ MaxDepth = std::max(MaxDepth, SSD->getDepth(SU));
+ }
+ }
+
+ unsigned getLatency() { return Latency; }
+
+ unsigned getMaxDepth() { return MaxDepth; }
+
+ void clear() {
+ Nodes.clear();
+ RecMII = 0;
+ HasRecurrence = false;
+ MaxMOV = 0;
+ MaxDepth = 0;
+ Colocate = 0;
+ ExceedPressure = nullptr;
+ }
+
+ operator SetVector<SUnit *> &() { return Nodes; }
+
+ /// Sort the node sets by importance. First, rank them by recurrence MII,
+ /// then by mobility (least mobile done first), and finally by depth.
+ /// Each node set may contain a colocate value which is used as the first
+ /// tie breaker, if it's set.
+ bool operator>(const NodeSet &RHS) const {
+ if (RecMII == RHS.RecMII) {
+ if (Colocate != 0 && RHS.Colocate != 0 && Colocate != RHS.Colocate)
+ return Colocate < RHS.Colocate;
+ if (MaxMOV == RHS.MaxMOV)
+ return MaxDepth > RHS.MaxDepth;
+ return MaxMOV < RHS.MaxMOV;
+ }
+ return RecMII > RHS.RecMII;
+ }
+
+ bool operator==(const NodeSet &RHS) const {
+ return RecMII == RHS.RecMII && MaxMOV == RHS.MaxMOV &&
+ MaxDepth == RHS.MaxDepth;
+ }
+
+ bool operator!=(const NodeSet &RHS) const { return !operator==(RHS); }
+
+ iterator begin() { return Nodes.begin(); }
+ iterator end() { return Nodes.end(); }
+ void print(raw_ostream &os) const;
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ LLVM_DUMP_METHOD void dump() const;
+#endif
+};
+
+/// 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
+/// the algorithm finshes, the schedule is collapsed into a single stage,
+/// which represents instructions from different loop iterations.
+///
+/// The SMS algorithm allows negative values for cycles, so the first cycle
+/// in the schedule is the smallest cycle value.
+class SMSchedule {
+private:
+ /// Map from execution cycle to instructions.
+ DenseMap<int, std::deque<SUnit *>> ScheduledInstrs;
+
+ /// Map from instruction to execution cycle.
+ std::map<SUnit *, int> InstrToCycle;
+
+ /// Map for each register and the max difference between its uses and def.
+ /// The first element in the pair is the max difference in stages. The
+ /// second is true if the register defines a Phi value and loop value is
+ /// scheduled before the Phi.
+ std::map<unsigned, std::pair<unsigned, bool>> RegToStageDiff;
+
+ /// Keep track of the first cycle value in the schedule. It starts
+ /// as zero, but the algorithm allows negative values.
+ int FirstCycle = 0;
+
+ /// Keep track of the last cycle value in the schedule.
+ int LastCycle = 0;
+
+ /// The initiation interval (II) for the schedule.
+ int InitiationInterval = 0;
+
+ /// Target machine information.
+ const TargetSubtargetInfo &ST;
+
+ /// Virtual register information.
+ MachineRegisterInfo &MRI;
+
+ std::unique_ptr<DFAPacketizer> Resources;
+
+public:
+ SMSchedule(MachineFunction *mf)
+ : ST(mf->getSubtarget()), MRI(mf->getRegInfo()),
+ Resources(ST.getInstrInfo()->CreateTargetScheduleState(ST)) {}
+
+ void reset() {
+ ScheduledInstrs.clear();
+ InstrToCycle.clear();
+ RegToStageDiff.clear();
+ FirstCycle = 0;
+ LastCycle = 0;
+ InitiationInterval = 0;
+ }
+
+ /// Set the initiation interval for this schedule.
+ void setInitiationInterval(int ii) { InitiationInterval = ii; }
+
+ /// Return the first cycle in the completed schedule. This
+ /// can be a negative value.
+ int getFirstCycle() const { return FirstCycle; }
+
+ /// Return the last cycle in the finalized schedule.
+ int getFinalCycle() const { return FirstCycle + InitiationInterval - 1; }
+
+ /// Return the cycle of the earliest scheduled instruction in the dependence
+ /// chain.
+ int earliestCycleInChain(const SDep &Dep);
+
+ /// Return the cycle of the latest scheduled instruction in the dependence
+ /// chain.
+ int latestCycleInChain(const SDep &Dep);
+
+ void computeStart(SUnit *SU, int *MaxEarlyStart, int *MinLateStart,
+ int *MinEnd, int *MaxStart, int II, SwingSchedulerDAG *DAG);
+ bool insert(SUnit *SU, int StartCycle, int EndCycle, int II);
+
+ /// Iterators for the cycle to instruction map.
+ using sched_iterator = DenseMap<int, std::deque<SUnit *>>::iterator;
+ using const_sched_iterator =
+ DenseMap<int, std::deque<SUnit *>>::const_iterator;
+
+ /// Return true if the instruction is scheduled at the specified stage.
+ bool isScheduledAtStage(SUnit *SU, unsigned StageNum) {
+ return (stageScheduled(SU) == (int)StageNum);
+ }
+
+ /// Return the stage for a scheduled instruction. Return -1 if
+ /// the instruction has not been scheduled.
+ int stageScheduled(SUnit *SU) const {
+ std::map<SUnit *, int>::const_iterator it = InstrToCycle.find(SU);
+ if (it == InstrToCycle.end())
+ return -1;
+ return (it->second - FirstCycle) / InitiationInterval;
+ }
+
+ /// Return the cycle for a scheduled instruction. This function normalizes
+ /// the first cycle to be 0.
+ unsigned cycleScheduled(SUnit *SU) const {
+ std::map<SUnit *, int>::const_iterator it = InstrToCycle.find(SU);
+ assert(it != InstrToCycle.end() && "Instruction hasn't been scheduled.");
+ return (it->second - FirstCycle) % InitiationInterval;
+ }
+
+ /// Return the maximum stage count needed for this schedule.
+ unsigned getMaxStageCount() {
+ return (LastCycle - FirstCycle) / InitiationInterval;
+ }
+
+ /// Return the max. number of stages/iterations that can occur between a
+ /// register definition and its uses.
+ unsigned getStagesForReg(int Reg, unsigned CurStage) {
+ std::pair<unsigned, bool> Stages = RegToStageDiff[Reg];
+ if (CurStage > getMaxStageCount() && Stages.first == 0 && Stages.second)
+ return 1;
+ return Stages.first;
+ }
+
+ /// The number of stages for a Phi is a little different than other
+ /// instructions. The minimum value computed in RegToStageDiff is 1
+ /// because we assume the Phi is needed for at least 1 iteration.
+ /// This is not the case if the loop value is scheduled prior to the
+ /// Phi in the same stage. This function returns the number of stages
+ /// or iterations needed between the Phi definition and any uses.
+ unsigned getStagesForPhi(int Reg) {
+ std::pair<unsigned, bool> Stages = RegToStageDiff[Reg];
+ if (Stages.second)
+ return Stages.first;
+ return Stages.first - 1;
+ }
+
+ /// Return the instructions that are scheduled at the specified cycle.
+ std::deque<SUnit *> &getInstructions(int cycle) {
+ return ScheduledInstrs[cycle];
+ }
+
+ bool isValidSchedule(SwingSchedulerDAG *SSD);
+ void finalizeSchedule(SwingSchedulerDAG *SSD);
+ void orderDependence(SwingSchedulerDAG *SSD, SUnit *SU,
+ std::deque<SUnit *> &Insts);
+ bool isLoopCarried(SwingSchedulerDAG *SSD, MachineInstr &Phi);
+ bool isLoopCarriedDefOfUse(SwingSchedulerDAG *SSD, MachineInstr *Def,
+ MachineOperand &MO);
+ void print(raw_ostream &os) const;
+ void dump() const;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_CODEGEN_MACHINEPIPELINER_H
diff --git a/linux-x64/clang/include/llvm/CodeGen/MachinePostDominators.h b/linux-x64/clang/include/llvm/CodeGen/MachinePostDominators.h
index c6a4159..b67e6b5 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachinePostDominators.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MachineRegionInfo.h b/linux-x64/clang/include/llvm/CodeGen/MachineRegionInfo.h
index 8394b58..6d9fb9b 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineRegionInfo.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MachineRegisterInfo.h b/linux-x64/clang/include/llvm/CodeGen/MachineRegisterInfo.h
index a6836a5..d25cd98 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -689,15 +688,14 @@
unsigned MinNumRegs = 0);
/// Constrain the register class or the register bank of the virtual register
- /// \p Reg to be a common subclass and a common bank of both registers
- /// provided respectively. Do nothing if any of the attributes (classes,
- /// banks, or low-level types) of the registers are deemed incompatible, or if
- /// the resulting register will have a class smaller than before and of size
- /// less than \p MinNumRegs. Return true if such register attributes exist,
- /// false otherwise.
+ /// \p Reg (and low-level type) to be a common subclass or a common bank of
+ /// both registers provided respectively (and a common low-level type). Do
+ /// nothing if any of the attributes (classes, banks, or low-level types) of
+ /// the registers are deemed incompatible, or if the resulting register will
+ /// have a class smaller than before and of size less than \p MinNumRegs.
+ /// Return true if such register attributes exist, false otherwise.
///
- /// \note Assumes that each register has either a low-level type or a class
- /// assigned, but not both. Use this method instead of constrainRegClass and
+ /// \note Use this method instead of constrainRegClass and
/// RegisterBankInfo::constrainGenericRegister everywhere but SelectionDAG
/// ISel / FastISel and GlobalISel's InstructionSelect pass respectively.
bool constrainRegAttrs(unsigned Reg, unsigned ConstrainingReg,
diff --git a/linux-x64/clang/include/llvm/CodeGen/MachineSSAUpdater.h b/linux-x64/clang/include/llvm/CodeGen/MachineSSAUpdater.h
index 5e91246..0319ec7 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineSSAUpdater.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MachineScheduler.h b/linux-x64/clang/include/llvm/CodeGen/MachineScheduler.h
index 6003b1b..7057998 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineScheduler.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -132,17 +131,19 @@
/// MachineSchedRegistry provides a selection of available machine instruction
/// schedulers.
-class MachineSchedRegistry : public MachinePassRegistryNode {
+class MachineSchedRegistry
+ : public MachinePassRegistryNode<
+ ScheduleDAGInstrs *(*)(MachineSchedContext *)> {
public:
using ScheduleDAGCtor = ScheduleDAGInstrs *(*)(MachineSchedContext *);
// RegisterPassParser requires a (misnamed) FunctionPassCtor type.
using FunctionPassCtor = ScheduleDAGCtor;
- static MachinePassRegistry Registry;
+ static MachinePassRegistry<ScheduleDAGCtor> Registry;
MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C)
- : MachinePassRegistryNode(N, D, (MachinePassCtor)C) {
+ : MachinePassRegistryNode(N, D, C) {
Registry.Add(this);
}
@@ -158,7 +159,7 @@
return (MachineSchedRegistry *)Registry.getList();
}
- static void setListener(MachinePassRegistryListener *L) {
+ static void setListener(MachinePassRegistryListener<FunctionPassCtor> *L) {
Registry.setListener(L);
}
};
@@ -792,7 +793,7 @@
/// Represent the type of SchedCandidate found within a single queue.
/// pickNodeBidirectional depends on these listed by decreasing priority.
enum CandReason : uint8_t {
- NoCand, Only1, PhysRegCopy, RegExcess, RegCritical, Stall, Cluster, Weak,
+ NoCand, Only1, PhysReg, RegExcess, RegCritical, Stall, Cluster, Weak,
RegMax, ResourceReduce, ResourceDemand, BotHeightReduce, BotPathReduce,
TopDepthReduce, TopPathReduce, NextDefUse, NodeOrder};
@@ -926,7 +927,7 @@
const TargetRegisterInfo *TRI,
const MachineFunction &MF);
unsigned getWeakLeft(const SUnit *SU, bool isTop);
-int biasPhysRegCopy(const SUnit *SU, bool isTop);
+int biasPhysReg(const SUnit *SU, bool isTop);
/// GenericScheduler shrinks the unscheduled zone using heuristics to balance
/// the schedule.
@@ -1004,7 +1005,7 @@
const RegPressureTracker &RPTracker,
SchedCandidate &Candidate);
- void reschedulePhysRegCopies(SUnit *SU, bool isTop);
+ void reschedulePhysReg(SUnit *SU, bool isTop);
};
/// PostGenericScheduler - Interface to the scheduling algorithm used by
diff --git a/linux-x64/clang/include/llvm/CodeGen/MachineTraceMetrics.h b/linux-x64/clang/include/llvm/CodeGen/MachineTraceMetrics.h
index 9d8db39..0259895 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineTraceMetrics.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/MacroFusion.h b/linux-x64/clang/include/llvm/CodeGen/MacroFusion.h
index a77226d..3a140fe 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MacroFusion.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/PBQP/CostAllocator.h b/linux-x64/clang/include/llvm/CodeGen/PBQP/CostAllocator.h
index bde451a..0d6d8a3 100644
--- a/linux-x64/clang/include/llvm/CodeGen/PBQP/CostAllocator.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/PBQP/Graph.h b/linux-x64/clang/include/llvm/CodeGen/PBQP/Graph.h
index a6d88b0..c2cd6da 100644
--- a/linux-x64/clang/include/llvm/CodeGen/PBQP/Graph.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/PBQP/Math.h b/linux-x64/clang/include/llvm/CodeGen/PBQP/Math.h
index d1432a3..8b014cc 100644
--- a/linux-x64/clang/include/llvm/CodeGen/PBQP/Math.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/PBQP/ReductionRules.h b/linux-x64/clang/include/llvm/CodeGen/PBQP/ReductionRules.h
index 21b9902..51822d0 100644
--- a/linux-x64/clang/include/llvm/CodeGen/PBQP/ReductionRules.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/PBQP/Solution.h b/linux-x64/clang/include/llvm/CodeGen/PBQP/Solution.h
index 4d4379f..d5b1474 100644
--- a/linux-x64/clang/include/llvm/CodeGen/PBQP/Solution.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/PBQPRAConstraint.h b/linux-x64/clang/include/llvm/CodeGen/PBQPRAConstraint.h
index 995467d..876ab97 100644
--- a/linux-x64/clang/include/llvm/CodeGen/PBQPRAConstraint.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/ParallelCG.h b/linux-x64/clang/include/llvm/CodeGen/ParallelCG.h
index dbf09ea..a44715d 100644
--- a/linux-x64/clang/include/llvm/CodeGen/ParallelCG.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/Passes.h b/linux-x64/clang/include/llvm/CodeGen/Passes.h
index cb12b14..c59473a 100644
--- a/linux-x64/clang/include/llvm/CodeGen/Passes.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -379,14 +378,20 @@
///
FunctionPass *createInterleavedAccessPass();
+ /// InterleavedLoadCombines Pass - This pass identifies interleaved loads and
+ /// combines them into wide loads detectable by InterleavedAccessPass
+ ///
+ FunctionPass *createInterleavedLoadCombinePass();
+
/// LowerEmuTLS - This pass generates __emutls_[vt].xyz variables for all
/// TLS variables for the emulated TLS model.
///
ModulePass *createLowerEmuTLSPass();
- /// This pass lowers the \@llvm.load.relative intrinsic to instructions.
- /// This is unsafe to do earlier because a pass may combine the constant
- /// initializer into the load, which may result in an overflowing evaluation.
+ /// This pass lowers the \@llvm.load.relative and \@llvm.objc.* intrinsics to
+ /// instructions. This is unsafe to do earlier because a pass may combine the
+ /// constant initializer into the load, which may result in an overflowing
+ /// evaluation.
ModulePass *createPreISelIntrinsicLoweringPass();
/// GlobalMerge - This pass merges internal (by default) globals into structs
diff --git a/linux-x64/clang/include/llvm/CodeGen/PreISelIntrinsicLowering.h b/linux-x64/clang/include/llvm/CodeGen/PreISelIntrinsicLowering.h
index 7a007eb..73d7d77 100644
--- a/linux-x64/clang/include/llvm/CodeGen/PreISelIntrinsicLowering.h
+++ b/linux-x64/clang/include/llvm/CodeGen/PreISelIntrinsicLowering.h
@@ -1,13 +1,13 @@
//===- 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
//
//===----------------------------------------------------------------------===//
//
-// This pass implements IR lowering for the llvm.load.relative intrinsic.
+// This pass implements IR lowering for the llvm.load.relative and llvm.objc.*
+// intrinsics.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_PREISELINTRINSICLOWERING_H
diff --git a/linux-x64/clang/include/llvm/CodeGen/PseudoSourceValue.h b/linux-x64/clang/include/llvm/CodeGen/PseudoSourceValue.h
index f66191b..4920f23 100644
--- a/linux-x64/clang/include/llvm/CodeGen/PseudoSourceValue.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/ReachingDefAnalysis.h b/linux-x64/clang/include/llvm/CodeGen/ReachingDefAnalysis.h
index b21b745..a599fb6 100644
--- a/linux-x64/clang/include/llvm/CodeGen/ReachingDefAnalysis.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/RegAllocPBQP.h b/linux-x64/clang/include/llvm/CodeGen/RegAllocPBQP.h
index ba97630..f7f9224 100644
--- a/linux-x64/clang/include/llvm/CodeGen/RegAllocPBQP.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/RegAllocRegistry.h b/linux-x64/clang/include/llvm/CodeGen/RegAllocRegistry.h
index 481747d..7077aa3 100644
--- a/linux-x64/clang/include/llvm/CodeGen/RegAllocRegistry.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -26,14 +25,14 @@
/// RegisterRegAlloc class - Track the registration of register allocators.
///
//===----------------------------------------------------------------------===//
-class RegisterRegAlloc : public MachinePassRegistryNode {
+class RegisterRegAlloc : public MachinePassRegistryNode<FunctionPass *(*)()> {
public:
using FunctionPassCtor = FunctionPass *(*)();
- static MachinePassRegistry Registry;
+ static MachinePassRegistry<FunctionPassCtor> Registry;
RegisterRegAlloc(const char *N, const char *D, FunctionPassCtor C)
- : MachinePassRegistryNode(N, D, (MachinePassCtor)C) {
+ : MachinePassRegistryNode(N, D, C) {
Registry.Add(this);
}
@@ -48,15 +47,11 @@
return (RegisterRegAlloc *)Registry.getList();
}
- static FunctionPassCtor getDefault() {
- return (FunctionPassCtor)Registry.getDefault();
- }
+ static FunctionPassCtor getDefault() { return Registry.getDefault(); }
- static void setDefault(FunctionPassCtor C) {
- Registry.setDefault((MachinePassCtor)C);
- }
+ static void setDefault(FunctionPassCtor C) { Registry.setDefault(C); }
- static void setListener(MachinePassRegistryListener *L) {
+ static void setListener(MachinePassRegistryListener<FunctionPassCtor> *L) {
Registry.setListener(L);
}
};
diff --git a/linux-x64/clang/include/llvm/CodeGen/RegisterClassInfo.h b/linux-x64/clang/include/llvm/CodeGen/RegisterClassInfo.h
index 97113c5..14af5c4 100644
--- a/linux-x64/clang/include/llvm/CodeGen/RegisterClassInfo.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/RegisterPressure.h b/linux-x64/clang/include/llvm/CodeGen/RegisterPressure.h
index 79054b9..5bbaa03 100644
--- a/linux-x64/clang/include/llvm/CodeGen/RegisterPressure.h
+++ b/linux-x64/clang/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 @@
}
};
-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/linux-x64/clang/include/llvm/CodeGen/RegisterScavenging.h b/linux-x64/clang/include/llvm/CodeGen/RegisterScavenging.h
index b6bd028..478ea38 100644
--- a/linux-x64/clang/include/llvm/CodeGen/RegisterScavenging.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/RegisterUsageInfo.h b/linux-x64/clang/include/llvm/CodeGen/RegisterUsageInfo.h
index efd175e..3355455 100644
--- a/linux-x64/clang/include/llvm/CodeGen/RegisterUsageInfo.h
+++ b/linux-x64/clang/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
@@ -29,7 +28,7 @@
namespace llvm {
class Function;
-class TargetMachine;
+class LLVMTargetMachine;
class PhysicalRegisterUsageInfo : public ImmutablePass {
public:
@@ -41,7 +40,7 @@
}
/// Set TargetMachine which is used to print analysis.
- void setTargetMachine(const TargetMachine &TM);
+ void setTargetMachine(const LLVMTargetMachine &TM);
bool doInitialization(Module &M) override;
@@ -63,7 +62,7 @@
/// and 1 means content of register will be preserved around function call.
DenseMap<const Function *, std::vector<uint32_t>> RegMasks;
- const TargetMachine *TM;
+ const LLVMTargetMachine *TM;
};
} // end namespace llvm
diff --git a/linux-x64/clang/include/llvm/CodeGen/ResourcePriorityQueue.h b/linux-x64/clang/include/llvm/CodeGen/ResourcePriorityQueue.h
index 8d582ee..81587a3 100644
--- a/linux-x64/clang/include/llvm/CodeGen/ResourcePriorityQueue.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/RuntimeLibcalls.h b/linux-x64/clang/include/llvm/CodeGen/RuntimeLibcalls.h
index 28567a1..f71f39e 100644
--- a/linux-x64/clang/include/llvm/CodeGen/RuntimeLibcalls.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/SDNodeProperties.td b/linux-x64/clang/include/llvm/CodeGen/SDNodeProperties.td
index 83bbab2..d25e0bd 100644
--- a/linux-x64/clang/include/llvm/CodeGen/SDNodeProperties.td
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/ScheduleDAG.h b/linux-x64/clang/include/llvm/CodeGen/ScheduleDAG.h
index f2b0727..68614dd 100644
--- a/linux-x64/clang/include/llvm/CodeGen/ScheduleDAG.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -33,15 +32,15 @@
namespace llvm {
template<class Graph> class GraphWriter;
+class LLVMTargetMachine;
class MachineFunction;
class MachineRegisterInfo;
class MCInstrDesc;
struct MCSchedClassDesc;
-class ScheduleDAG;
class SDNode;
class SUnit;
+class ScheduleDAG;
class TargetInstrInfo;
-class TargetMachine;
class TargetRegisterClass;
class TargetRegisterInfo;
@@ -239,9 +238,6 @@
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:
@@ -558,7 +554,7 @@
class ScheduleDAG {
public:
- const TargetMachine &TM; ///< Target processor
+ const LLVMTargetMachine &TM; ///< Target processor
const TargetInstrInfo *TII; ///< Target instruction information
const TargetRegisterInfo *TRI; ///< Target processor register info
MachineFunction &MF; ///< Machine function
diff --git a/linux-x64/clang/include/llvm/CodeGen/ScheduleDAGInstrs.h b/linux-x64/clang/include/llvm/CodeGen/ScheduleDAGInstrs.h
index daad181..fa7f886 100644
--- a/linux-x64/clang/include/llvm/CodeGen/ScheduleDAGInstrs.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/ScheduleDAGMutation.h b/linux-x64/clang/include/llvm/CodeGen/ScheduleDAGMutation.h
index 5c23642..d1dd728 100644
--- a/linux-x64/clang/include/llvm/CodeGen/ScheduleDAGMutation.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/ScheduleDFS.h b/linux-x64/clang/include/llvm/CodeGen/ScheduleDFS.h
index 3ecc033..d60deab 100644
--- a/linux-x64/clang/include/llvm/CodeGen/ScheduleDFS.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/ScheduleHazardRecognizer.h b/linux-x64/clang/include/llvm/CodeGen/ScheduleHazardRecognizer.h
index ace4a2d..37590f4 100644
--- a/linux-x64/clang/include/llvm/CodeGen/ScheduleHazardRecognizer.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/SchedulerRegistry.h b/linux-x64/clang/include/llvm/CodeGen/SchedulerRegistry.h
index badf927..0ccfaaf 100644
--- a/linux-x64/clang/include/llvm/CodeGen/SchedulerRegistry.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -29,16 +28,19 @@
class ScheduleDAGSDNodes;
class SelectionDAGISel;
-class RegisterScheduler : public MachinePassRegistryNode {
+class RegisterScheduler
+ : public MachinePassRegistryNode<
+ ScheduleDAGSDNodes *(*)(SelectionDAGISel *, CodeGenOpt::Level)> {
public:
using FunctionPassCtor = ScheduleDAGSDNodes *(*)(SelectionDAGISel*,
CodeGenOpt::Level);
- static MachinePassRegistry Registry;
+ static MachinePassRegistry<FunctionPassCtor> Registry;
RegisterScheduler(const char *N, const char *D, FunctionPassCtor C)
- : MachinePassRegistryNode(N, D, (MachinePassCtor)C)
- { Registry.Add(this); }
+ : MachinePassRegistryNode(N, D, C) {
+ Registry.Add(this);
+ }
~RegisterScheduler() { Registry.Remove(this); }
@@ -51,7 +53,7 @@
return (RegisterScheduler *)Registry.getList();
}
- static void setListener(MachinePassRegistryListener *L) {
+ static void setListener(MachinePassRegistryListener<FunctionPassCtor> *L) {
Registry.setListener(L);
}
};
diff --git a/linux-x64/clang/include/llvm/CodeGen/ScoreboardHazardRecognizer.h b/linux-x64/clang/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
index 3f75d10..ac67f30 100644
--- a/linux-x64/clang/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/SelectionDAG.h b/linux-x64/clang/include/llvm/CodeGen/SelectionDAG.h
index 973a3dd..dfd1d49 100644
--- a/linux-x64/clang/include/llvm/CodeGen/SelectionDAG.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -308,6 +307,9 @@
: DAGUpdateListener(DAG), Callback(std::move(Callback)) {}
void NodeDeleted(SDNode *N, SDNode *E) override { Callback(N, E); }
+
+ private:
+ virtual void anchor();
};
/// When true, additional steps are taken to
@@ -786,24 +788,6 @@
/// value assuming it was the smaller SrcTy value.
SDValue getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT VT);
- /// Return an operation which will any-extend the low lanes of the operand
- /// into the specified vector type. For example,
- /// this can convert a v16i8 into a v4i32 by any-extending the low four
- /// lanes of the operand from i8 to i32.
- SDValue getAnyExtendVectorInReg(SDValue Op, const SDLoc &DL, EVT VT);
-
- /// Return an operation which will sign extend the low lanes of the operand
- /// into the specified vector type. For example,
- /// this can convert a v16i8 into a v4i32 by sign extending the low four
- /// lanes of the operand from i8 to i32.
- SDValue getSignExtendVectorInReg(SDValue Op, const SDLoc &DL, EVT VT);
-
- /// Return an operation which will zero extend the low lanes of the operand
- /// into the specified vector type. For example,
- /// this can convert a v16i8 into a v4i32 by zero extending the low four
- /// lanes of the operand from i8 to i32.
- SDValue getZeroExtendVectorInReg(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.
@@ -947,41 +931,45 @@
Type *SizeTy, unsigned ElemSz, bool isTailCall,
MachinePointerInfo DstPtrInfo);
- /// Helper function to make it easier to build SetCC's if you just
- /// have an ISD::CondCode instead of an SDValue.
- ///
+ /// Helper function to make it easier to build SetCC's if you just have an
+ /// ISD::CondCode instead of an SDValue.
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS,
ISD::CondCode Cond) {
assert(LHS.getValueType().isVector() == RHS.getValueType().isVector() &&
- "Cannot compare scalars to vectors");
+ "Cannot compare scalars to vectors");
assert(LHS.getValueType().isVector() == VT.isVector() &&
- "Cannot compare scalars to vectors");
+ "Cannot compare scalars to vectors");
assert(Cond != ISD::SETCC_INVALID &&
- "Cannot create a setCC of an invalid node.");
+ "Cannot create a setCC of an invalid node.");
return getNode(ISD::SETCC, DL, VT, LHS, RHS, getCondCode(Cond));
}
- /// Helper function to make it easier to build Select's if you just
- /// have operands and don't want to check for vector.
+ /// Helper function to make it easier to build Select's if you just have
+ /// operands and don't want to check for vector.
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS,
SDValue RHS) {
assert(LHS.getValueType() == RHS.getValueType() &&
"Cannot use select on differing types");
assert(VT.isVector() == LHS.getValueType().isVector() &&
"Cannot mix vectors and scalars");
- return getNode(Cond.getValueType().isVector() ? ISD::VSELECT : ISD::SELECT, DL, VT,
- Cond, LHS, RHS);
+ auto Opcode = Cond.getValueType().isVector() ? ISD::VSELECT : ISD::SELECT;
+ return getNode(Opcode, DL, VT, Cond, LHS, RHS);
}
- /// Helper function to make it easier to build SelectCC's if you
- /// just have an ISD::CondCode instead of an SDValue.
- ///
+ /// Helper function to make it easier to build SelectCC's if you just have an
+ /// ISD::CondCode instead of an SDValue.
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True,
SDValue False, ISD::CondCode Cond) {
- return getNode(ISD::SELECT_CC, DL, True.getValueType(),
- LHS, RHS, True, False, getCondCode(Cond));
+ return getNode(ISD::SELECT_CC, DL, True.getValueType(), LHS, RHS, True,
+ False, getCondCode(Cond));
}
+ /// Try to simplify a select/vselect into 1 of its operands or a constant.
+ SDValue simplifySelect(SDValue Cond, SDValue TVal, SDValue FVal);
+
+ /// Try to simplify a shift into 1 of its operands or a constant.
+ SDValue simplifyShift(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,
@@ -1004,10 +992,6 @@
/// 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
@@ -1142,6 +1126,13 @@
/// Expand the specified \c ISD::VACOPY node as the Legalize pass would.
SDValue expandVACopy(SDNode *Node);
+ /// Returs an GlobalAddress of the function from the current module with
+ /// name matching the given ExternalSymbol. Additionally can provide the
+ /// matched function.
+ /// Panics the function doesn't exists.
+ SDValue getSymbolFunctionGlobalAddress(SDValue Op,
+ Function **TargetFunction = nullptr);
+
/// *Mutate* the specified node in-place to have the
/// specified operands. If the resultant node already exists in the DAG,
/// this does not modify the specified node, instead it returns the node that
@@ -1158,6 +1149,11 @@
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,
@@ -1362,21 +1358,20 @@
/// 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();
}
@@ -1399,11 +1394,11 @@
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,
@@ -1446,18 +1441,6 @@
KnownBits computeKnownBits(SDValue Op, const APInt &DemandedElts,
unsigned Depth = 0) const;
- /// \copydoc SelectionDAG::computeKnownBits(SDValue,unsigned)
- void computeKnownBits(SDValue Op, KnownBits &Known,
- unsigned Depth = 0) const {
- Known = computeKnownBits(Op, Depth);
- }
-
- /// \copydoc SelectionDAG::computeKnownBits(SDValue,const APInt&,unsigned)
- void computeKnownBits(SDValue Op, KnownBits &Known, const APInt &DemandedElts,
- unsigned Depth = 0) const {
- Known = computeKnownBits(Op, DemandedElts, Depth);
- }
-
/// Used to represent the possible overflow behavior of an operation.
/// Never: the operation cannot overflow.
/// Always: the operation will always overflow.
@@ -1529,6 +1512,18 @@
/// allow an 'add' to be transformed into an 'or'.
bool haveNoCommonBitsSet(SDValue A, SDValue B) const;
+ /// Test whether \p V has a splatted value for all the demanded elements.
+ ///
+ /// On success \p UndefElts will indicate the elements that have UNDEF
+ /// values instead of the splat value, this is only guaranteed to be correct
+ /// for \p DemandedElts.
+ ///
+ /// NOTE: The function will return true for a demanded splat of UNDEF values.
+ bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts);
+
+ /// Test whether \p V has a splatted value.
+ bool isSplatValue(SDValue V, bool AllowUndefs = false);
+
/// 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
diff --git a/linux-x64/clang/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h b/linux-x64/clang/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h
index 5806064..f168b84 100644
--- a/linux-x64/clang/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
@@ -45,18 +44,24 @@
IsIndexSignExt(IsIndexSignExt) {}
SDValue getBase() { return Base; }
+ SDValue getBase() const { return Base; }
SDValue getIndex() { return Index; }
+ SDValue getIndex() const { return Index; }
- bool equalBaseIndex(BaseIndexOffset &Other, const SelectionDAG &DAG) {
+ bool equalBaseIndex(const BaseIndexOffset &Other,
+ const SelectionDAG &DAG) const {
int64_t Off;
return equalBaseIndex(Other, DAG, Off);
}
- bool equalBaseIndex(BaseIndexOffset &Other, const SelectionDAG &DAG,
- int64_t &Off);
+ bool equalBaseIndex(const BaseIndexOffset &Other, const SelectionDAG &DAG,
+ int64_t &Off) const;
/// Parses tree in Ptr for base, index, offset addresses.
- static BaseIndexOffset match(LSBaseSDNode *N, const SelectionDAG &DAG);
+ static BaseIndexOffset match(const LSBaseSDNode *N, const SelectionDAG &DAG);
+
+ void print(raw_ostream& OS) const;
+ void dump() const;
};
} // end namespace llvm
diff --git a/linux-x64/clang/include/llvm/CodeGen/SelectionDAGISel.h b/linux-x64/clang/include/llvm/CodeGen/SelectionDAGISel.h
index 86df0af..2acb922 100644
--- a/linux-x64/clang/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -132,6 +131,7 @@
OPC_CheckChild2Same, OPC_CheckChild3Same,
OPC_CheckPatternPredicate,
OPC_CheckPredicate,
+ OPC_CheckPredicateWithOperands,
OPC_CheckOpcode,
OPC_SwitchOpcode,
OPC_CheckType,
@@ -267,6 +267,17 @@
llvm_unreachable("Tblgen should generate the implementation of this!");
}
+ /// CheckNodePredicateWithOperands - This function is generated by tblgen in
+ /// the target.
+ /// It runs node predicate number PredNo and returns true if it succeeds or
+ /// false if it fails. The number is a private implementation detail to the
+ /// code tblgen produces.
+ virtual bool CheckNodePredicateWithOperands(
+ SDNode *N, unsigned PredNo,
+ const SmallVectorImpl<SDValue> &Operands) const {
+ llvm_unreachable("Tblgen should generate the implementation of this!");
+ }
+
virtual bool CheckComplexPattern(SDNode *Root, SDNode *Parent, SDValue N,
unsigned PatternNo,
SmallVectorImpl<std::pair<SDValue, SDNode*> > &Result) {
@@ -291,7 +302,7 @@
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/linux-x64/clang/include/llvm/CodeGen/SelectionDAGNodes.h b/linux-x64/clang/include/llvm/CodeGen/SelectionDAGNodes.h
index 28d27b7..c0dd9d1 100644
--- a/linux-x64/clang/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/linux-x64/clang/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 @@
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 @@
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.
@@ -672,6 +671,12 @@
case ISD::STRICT_FLOG2:
case ISD::STRICT_FRINT:
case ISD::STRICT_FNEARBYINT:
+ case ISD::STRICT_FMAXNUM:
+ case ISD::STRICT_FMINNUM:
+ case ISD::STRICT_FCEIL:
+ case ISD::STRICT_FFLOOR:
+ case ISD::STRICT_FROUND:
+ case ISD::STRICT_FTRUNC:
return true;
}
}
@@ -892,9 +897,17 @@
/// 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];
@@ -1122,6 +1135,10 @@
return Node->getConstantOperandVal(i);
}
+inline const APInt &SDValue::getConstantOperandAPInt(unsigned i) const {
+ return Node->getConstantOperandAPInt(i);
+}
+
inline bool SDValue::isTargetOpcode() const {
return Node->isTargetOpcode();
}
@@ -1350,6 +1367,8 @@
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 ||
@@ -1402,6 +1421,8 @@
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;
}
@@ -1530,6 +1551,10 @@
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;
@@ -1607,6 +1632,21 @@
/// Returns the SDNode if it is a constant splat BuildVector or constant float.
ConstantFPSDNode *isConstOrConstSplatFP(SDValue N, 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 by default).
+/// Build vector implicit truncation is not an issue for null values.
+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).
+/// Does not permit build vector implicit truncation.
+bool isOneOrOneSplat(SDValue V);
+
+/// Return true if the value is a constant -1 integer or a splatted vector of a
+/// constant -1 integer (with no undefs).
+/// Does not permit build vector implicit truncation.
+bool isAllOnesOrAllOnesSplat(SDValue V);
+
class GlobalAddressSDNode : public SDNode {
friend class SelectionDAG;
@@ -2466,15 +2506,18 @@
/// 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.
bool matchUnaryPredicate(SDValue Op,
- std::function<bool(ConstantSDNode *)> Match);
+ std::function<bool(ConstantSDNode *)> Match,
+ bool AllowUndefs = false);
/// 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.
bool matchBinaryPredicate(
SDValue LHS, SDValue RHS,
- std::function<bool(ConstantSDNode *, ConstantSDNode *)> Match);
-
+ std::function<bool(ConstantSDNode *, ConstantSDNode *)> Match,
+ bool AllowUndefs = false);
} // end namespace ISD
} // end namespace llvm
diff --git a/linux-x64/clang/include/llvm/CodeGen/SelectionDAGTargetInfo.h b/linux-x64/clang/include/llvm/CodeGen/SelectionDAGTargetInfo.h
index 45c1df4..7c9f57b 100644
--- a/linux-x64/clang/include/llvm/CodeGen/SelectionDAGTargetInfo.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/SlotIndexes.h b/linux-x64/clang/include/llvm/CodeGen/SlotIndexes.h
index 5508222..63461d6 100644
--- a/linux-x64/clang/include/llvm/CodeGen/SlotIndexes.h
+++ b/linux-x64/clang/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 @@
}
};
- template <> struct isPodLike<SlotIndex> { static const bool value = true; };
-
inline raw_ostream& operator<<(raw_ostream &os, SlotIndex li) {
li.print(os);
return os;
@@ -413,10 +410,14 @@
/// Returns the base index for the given instruction.
SlotIndex getInstructionIndex(const MachineInstr &MI) const {
// Instructions inside a bundle have the same number as the bundle itself.
- const MachineInstr &BundleStart = *getBundleStart(MI.getIterator());
- assert(!BundleStart.isDebugInstr() &&
+ auto BundleStart = getBundleStart(MI.getIterator());
+ auto BundleEnd = getBundleEnd(MI.getIterator());
+ // Use the first non-debug instruction in the bundle to get SlotIndex.
+ const MachineInstr &BundleNonDebug =
+ *skipDebugInstructionsForward(BundleStart, BundleEnd);
+ assert(!BundleNonDebug.isDebugInstr() &&
"Could not use a debug instruction to query mi2iMap.");
- Mi2IndexMap::const_iterator itr = mi2iMap.find(&BundleStart);
+ Mi2IndexMap::const_iterator itr = mi2iMap.find(&BundleNonDebug);
assert(itr != mi2iMap.end() && "Instruction not found in maps.");
return itr->second;
}
@@ -444,7 +445,7 @@
/// MI is not required to have an index.
SlotIndex getIndexBefore(const MachineInstr &MI) const {
const MachineBasicBlock *MBB = MI.getParent();
- assert(MBB && "MI must be inserted inna basic block");
+ assert(MBB && "MI must be inserted in a basic block");
MachineBasicBlock::const_iterator I = MI, B = MBB->begin();
while (true) {
if (I == B)
@@ -461,7 +462,7 @@
/// MI is not required to have an index.
SlotIndex getIndexAfter(const MachineInstr &MI) const {
const MachineBasicBlock *MBB = MI.getParent();
- assert(MBB && "MI must be inserted inna basic block");
+ assert(MBB && "MI must be inserted in a basic block");
MachineBasicBlock::const_iterator I = MI, E = MBB->end();
while (true) {
++I;
diff --git a/linux-x64/clang/include/llvm/CodeGen/StackMaps.h b/linux-x64/clang/include/llvm/CodeGen/StackMaps.h
index e584a41..d7d88de 100644
--- a/linux-x64/clang/include/llvm/CodeGen/StackMaps.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
@@ -236,25 +235,6 @@
FnInfos.clear();
}
- /// Generate a stackmap record for a stackmap instruction.
- ///
- /// MI must be a raw STACKMAP, not a PATCHPOINT.
- void recordStackMap(const MachineInstr &MI);
-
- /// Generate a stackmap record for a patchpoint instruction.
- void recordPatchPoint(const MachineInstr &MI);
-
- /// Generate a stackmap record for a statepoint instruction.
- void recordStatepoint(const MachineInstr &MI);
-
- /// If there is any stack map data, create a stack map section and serialize
- /// the map info into it. This clears the stack map data structures
- /// afterwards.
- void serializeToStackMapSection();
-
-private:
- static const char *WSMP;
-
using LocationVec = SmallVector<Location, 8>;
using LiveOutVec = SmallVector<LiveOutReg, 8>;
using ConstantPool = MapVector<uint64_t, uint64_t>;
@@ -283,6 +263,31 @@
using FnInfoMap = MapVector<const MCSymbol *, FunctionInfo>;
using CallsiteInfoList = std::vector<CallsiteInfo>;
+ /// Generate a stackmap record for a stackmap instruction.
+ ///
+ /// MI must be a raw STACKMAP, not a PATCHPOINT.
+ void recordStackMap(const MachineInstr &MI);
+
+ /// Generate a stackmap record for a patchpoint instruction.
+ void recordPatchPoint(const MachineInstr &MI);
+
+ /// Generate a stackmap record for a statepoint instruction.
+ void recordStatepoint(const MachineInstr &MI);
+
+ /// If there is any stack map data, create a stack map section and serialize
+ /// the map info into it. This clears the stack map data structures
+ /// afterwards.
+ void serializeToStackMapSection();
+
+ /// Get call site info.
+ CallsiteInfoList &getCSInfos() { return CSInfos; }
+
+ /// Get function info.
+ FnInfoMap &getFnInfos() { return FnInfos; }
+
+private:
+ static const char *WSMP;
+
AsmPrinter &AP;
CallsiteInfoList CSInfos;
ConstantPool ConstPool;
diff --git a/linux-x64/clang/include/llvm/CodeGen/StackProtector.h b/linux-x64/clang/include/llvm/CodeGen/StackProtector.h
index a506ac6..ed52db3 100644
--- a/linux-x64/clang/include/llvm/CodeGen/StackProtector.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/TailDuplicator.h b/linux-x64/clang/include/llvm/CodeGen/TailDuplicator.h
index be6562c..358798d 100644
--- a/linux-x64/clang/include/llvm/CodeGen/TailDuplicator.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/TargetCallingConv.h b/linux-x64/clang/include/llvm/CodeGen/TargetCallingConv.h
index 7d138f5..f82c05d 100644
--- a/linux-x64/clang/include/llvm/CodeGen/TargetCallingConv.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/TargetFrameLowering.h b/linux-x64/clang/include/llvm/CodeGen/TargetFrameLowering.h
index f8effee..754ee5c 100644
--- a/linux-x64/clang/include/llvm/CodeGen/TargetFrameLowering.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -207,8 +206,11 @@
return false;
}
- /// Return true if the target needs to disable frame pointer elimination.
- virtual bool noFramePointerElim(const MachineFunction &MF) const;
+ /// Return true if the target wants to keep the frame pointer regardless of
+ /// the function attribute "frame-pointer".
+ virtual bool keepFramePointer(const MachineFunction &MF) const {
+ return false;
+ }
/// hasFP - Return true if the specified function should have a dedicated
/// frame pointer register. For most targets this is true only if the function
@@ -259,6 +261,17 @@
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
diff --git a/linux-x64/clang/include/llvm/CodeGen/TargetInstrInfo.h b/linux-x64/clang/include/llvm/CodeGen/TargetInstrInfo.h
index 1fa3de4..b732be6 100644
--- a/linux-x64/clang/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -429,6 +428,13 @@
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,
@@ -1136,11 +1142,11 @@
return false;
}
- /// Get the base register and byte offset of an instruction that reads/writes
+ /// Get the base operand and byte offset of an instruction that reads/writes
/// memory.
- virtual bool getMemOpBaseRegImmOfs(MachineInstr &MemOp, unsigned &BaseReg,
- int64_t &Offset,
- const TargetRegisterInfo *TRI) const {
+ virtual bool getMemOperandWithOffset(MachineInstr &MI,
+ MachineOperand *&BaseOp, int64_t &Offset,
+ const TargetRegisterInfo *TRI) const {
return false;
}
@@ -1164,8 +1170,8 @@
/// or
/// DAG->addMutation(createStoreClusterDAGMutation(DAG->TII, DAG->TRI));
/// to TargetPassConfig::createMachineScheduler() to have an effect.
- virtual bool shouldClusterMemOps(MachineInstr &FirstLdSt, unsigned BaseReg1,
- MachineInstr &SecondLdSt, unsigned BaseReg2,
+ virtual bool shouldClusterMemOps(MachineOperand &BaseOp1,
+ MachineOperand &BaseOp2,
unsigned NumLoads) const {
llvm_unreachable("target did not implement shouldClusterMemOps()");
}
@@ -1635,10 +1641,11 @@
"Target didn't implement TargetInstrInfo::getOutliningType!");
}
- /// Returns target-defined flags defining properties of the MBB for
- /// the outliner.
- virtual unsigned getMachineOutlinerMBBFlags(MachineBasicBlock &MBB) const {
- return 0x0;
+ /// Optional target hook that returns true if \p MBB is safe to outline from,
+ /// and returns any target-specific information in \p Flags.
+ virtual bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB,
+ unsigned &Flags) const {
+ return true;
}
/// Insert a custom frame for outlined functions.
diff --git a/linux-x64/clang/include/llvm/CodeGen/TargetLowering.h b/linux-x64/clang/include/llvm/CodeGen/TargetLowering.h
index a593907..fa71024 100644
--- a/linux-x64/clang/include/llvm/CodeGen/TargetLowering.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
///
@@ -195,7 +194,11 @@
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>;
@@ -269,6 +272,14 @@
return true;
}
+ /// Return true if it is profitable to convert a select of FP constants into
+ /// a constant pool load whose address depends on the select condition. The
+ /// parameter may be used to differentiate a select with FP compare from
+ /// integer compare.
+ virtual bool reduceSelectOfFPConstantLoads(bool IsFPSetCC) const {
+ return true;
+ }
+
/// Return true if multiple condition registers are available.
bool hasMultipleConditionRegisters() const {
return HasMultipleConditionRegisters;
@@ -279,7 +290,7 @@
/// Return the preferred vector type legalization action.
virtual TargetLoweringBase::LegalizeTypeAction
- getPreferredVectorAction(EVT VT) const {
+ getPreferredVectorAction(MVT VT) const {
// The default action for one element vectors is to scalarize
if (VT.getVectorNumElements() == 1)
return TypeScalarizeVector;
@@ -635,6 +646,13 @@
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.
@@ -797,6 +815,39 @@
return OpActions[(unsigned)VT.getSimpleVT().SimpleTy][Op];
}
+ /// Custom method defined by each target to indicate if an operation which
+ /// may require a scale is supported natively by the target.
+ /// If not, the operation is illegal.
+ virtual bool isSupportedFixedPointOperation(unsigned Op, EVT VT,
+ unsigned Scale) const {
+ return false;
+ }
+
+ /// Some fixed point operations may be natively supported by the target but
+ /// only for specific scales. This method allows for checking
+ /// if the width is supported by the target for a given operation that may
+ /// depend on scale.
+ LegalizeAction getFixedPointOperationAction(unsigned Op, EVT VT,
+ unsigned Scale) const {
+ auto Action = getOperationAction(Op, VT);
+ if (Action != Legal)
+ return Action;
+
+ // This operation is supported in this type but may only work on specific
+ // scales.
+ bool Supported;
+ switch (Op) {
+ default:
+ llvm_unreachable("Unexpected fixed point operation.");
+ case ISD::SMULFIX:
+ case ISD::UMULFIX:
+ Supported = isSupportedFixedPointOperation(Op, VT, Scale);
+ break;
+ }
+
+ return Supported ? Action : Expand;
+ }
+
LegalizeAction getStrictFPOperationAction(unsigned Op, EVT VT) const {
unsigned EqOpc;
switch (Op) {
@@ -819,6 +870,12 @@
case ISD::STRICT_FLOG2: EqOpc = ISD::FLOG2; break;
case ISD::STRICT_FRINT: EqOpc = ISD::FRINT; break;
case ISD::STRICT_FNEARBYINT: EqOpc = ISD::FNEARBYINT; break;
+ case ISD::STRICT_FMAXNUM: EqOpc = ISD::FMAXNUM; break;
+ case ISD::STRICT_FMINNUM: EqOpc = ISD::FMINNUM; break;
+ case ISD::STRICT_FCEIL: EqOpc = ISD::FCEIL; break;
+ case ISD::STRICT_FFLOOR: EqOpc = ISD::FFLOOR; break;
+ case ISD::STRICT_FROUND: EqOpc = ISD::FROUND; break;
+ case ISD::STRICT_FTRUNC: EqOpc = ISD::FTRUNC; break;
}
auto Action = getOperationAction(EqOpc, VT);
@@ -1207,13 +1264,15 @@
/// reduce runtime.
virtual bool ShouldShrinkFPConstant(EVT) const { return true; }
- // Return true if it is profitable to reduce the given load node to a smaller
- // type.
- //
- // e.g. (i16 (trunc (i32 (load x))) -> i16 load x should be performed
- virtual bool shouldReduceLoadWidth(SDNode *Load,
- ISD::LoadExtType ExtTy,
+ /// Return true if it is profitable to reduce a load to a smaller type.
+ /// Example: (i16 (trunc (i32 (load x))) -> i16 load x
+ virtual bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy,
EVT NewVT) const {
+ // By default, assume that it is cheaper to extract a subvector from a wide
+ // vector load rather than creating multiple narrow vector loads.
+ if (NewVT.isVector() && !Load->hasOneUse())
+ return false;
+
return true;
}
@@ -1467,7 +1526,7 @@
/// 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,
@@ -1668,8 +1727,9 @@
/// 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
@@ -1714,6 +1774,8 @@
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
@@ -1730,6 +1792,16 @@
return false;
}
+ /// Return true if it is more correct/profitable to use strict FP_TO_INT
+ /// conversion operations - canonicalizing the FP source value instead of
+ /// converting all cases and then selecting based on value.
+ /// This may be true if the target throws exceptions for out of bounds
+ /// conversions or has fast FP CMOV.
+ virtual bool shouldUseStrictFP_TO_INT(EVT FpVT, EVT IntVT,
+ bool IsSigned) const {
+ return false;
+ }
+
//===--------------------------------------------------------------------===//
// TargetLowering Configuration Methods - These methods should be invoked by
// the derived class constructor to configure this object for the target.
@@ -2058,6 +2130,14 @@
return true;
}
+ /// Return true if the specified immediate is legal for the value input of a
+ /// store instruction.
+ virtual bool isLegalStoreImmediate(int64_t Value) const {
+ // Default implementation assumes that at least 0 works since it is likely
+ // that a zero register exists or a zero immediate is allowed.
+ return Value == 0;
+ }
+
/// Return true if it's significantly cheaper to shift a vector by a uniform
/// scalar than by an amount which will vary across each lane. On x86, for
/// example, there is a "psllw" instruction for the former case, but no simple
@@ -2089,10 +2169,12 @@
case ISD::UADDO:
case ISD::ADDC:
case ISD::ADDE:
+ case ISD::SADDSAT:
+ case ISD::UADDSAT:
case ISD::FMINNUM:
case ISD::FMAXNUM:
- case ISD::FMINNAN:
- case ISD::FMAXNAN:
+ case ISD::FMINIMUM:
+ case ISD::FMAXIMUM:
return true;
default: return false;
}
@@ -2196,6 +2278,22 @@
return false;
}
+ /// Return true if sign-extension from FromTy to ToTy is cheaper than
+ /// zero-extension.
+ virtual bool isSExtCheaperThanZExt(EVT FromTy, EVT ToTy) const {
+ 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
@@ -2335,6 +2433,12 @@
return false;
}
+ /// Try to convert an extract element of a vector binary operation into an
+ /// extract element followed by a scalar operation.
+ virtual bool shouldScalarizeBinop(SDValue VecOp) const {
+ return false;
+ }
+
// 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 {
@@ -2817,32 +2921,28 @@
bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded,
TargetLoweringOpt &TLO) const;
- /// Helper for SimplifyDemandedBits that can simplify an operation with
- /// multiple uses. This function simplifies operand \p OpIdx of \p User and
- /// then updates \p User with the simplified version. No other uses of
- /// \p OpIdx are updated. If \p User is the only user of \p OpIdx, this
- /// function behaves exactly like function SimplifyDemandedBits declared
- /// below except that it also updates the DAG by calling
- /// DCI.CommitTargetLoweringOpt.
- bool SimplifyDemandedBits(SDNode *User, unsigned OpIdx, const APInt &Demanded,
- DAGCombinerInfo &DCI, TargetLoweringOpt &TLO) const;
-
- /// Look at Op. At this point, we know that only the DemandedMask bits of the
+ /// Look at Op. At this point, we know that only the DemandedBits bits of the
/// result of Op are ever used downstream. If we can use this information to
/// simplify Op, create a new simplified DAG node and return true, returning
/// the original and new nodes in Old and New. Otherwise, analyze the
/// expression and return a mask of KnownOne and KnownZero bits for the
/// expression (used to simplify the caller). The KnownZero/One bits may only
- /// be accurate for those bits in the DemandedMask.
+ /// be accurate for those bits in the Demanded masks.
/// \p AssumeSingleUse When this parameter is true, this function will
/// attempt to simplify \p Op even if there are multiple uses.
/// Callers are responsible for correctly updating the DAG based on the
/// results of this function, because simply replacing replacing TLO.Old
/// with TLO.New will be incorrect when this parameter is true and TLO.Old
/// has multiple uses.
- bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask,
- KnownBits &Known,
- TargetLoweringOpt &TLO,
+ bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedBits,
+ const APInt &DemandedElts, KnownBits &Known,
+ TargetLoweringOpt &TLO, unsigned Depth = 0,
+ bool AssumeSingleUse = false) const;
+
+ /// Helper wrapper around SimplifyDemandedBits, demanding all elements.
+ /// Adds Op back to the worklist upon success.
+ bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedBits,
+ KnownBits &Known, TargetLoweringOpt &TLO,
unsigned Depth = 0,
bool AssumeSingleUse = false) const;
@@ -2908,11 +3008,23 @@
/// elements, returning true on success. Otherwise, analyze the expression and
/// return a mask of KnownUndef and KnownZero elements for the expression
/// (used to simplify the caller). The KnownUndef/Zero elements may only be
- /// accurate for those bits in the DemandedMask
+ /// accurate for those bits in the DemandedMask.
virtual bool SimplifyDemandedVectorEltsForTargetNode(
SDValue Op, const APInt &DemandedElts, APInt &KnownUndef,
APInt &KnownZero, TargetLoweringOpt &TLO, unsigned Depth = 0) const;
+ /// Attempt to simplify any target nodes based on the demanded bits/elts,
+ /// returning true on success. Otherwise, analyze the
+ /// expression and return a mask of KnownOne and KnownZero bits for the
+ /// expression (used to simplify the caller). The KnownZero/One bits may only
+ /// be accurate for those bits in the Demanded masks.
+ virtual bool SimplifyDemandedBitsForTargetNode(SDValue Op,
+ const APInt &DemandedBits,
+ const APInt &DemandedElts,
+ KnownBits &Known,
+ TargetLoweringOpt &TLO,
+ unsigned Depth = 0) 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.
@@ -3000,6 +3112,15 @@
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:
@@ -3541,6 +3662,12 @@
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
//
@@ -3638,12 +3765,68 @@
SDValue LL = SDValue(), SDValue LH = SDValue(),
SDValue RL = SDValue(), SDValue RH = SDValue()) const;
+ /// Expand funnel shift.
+ /// \param N Node to expand
+ /// \param Result output after conversion
+ /// \returns True, if the expansion was successful, false otherwise
+ bool expandFunnelShift(SDNode *N, SDValue &Result, SelectionDAG &DAG) const;
+
+ /// Expand rotations.
+ /// \param N Node to expand
+ /// \param Result output after conversion
+ /// \returns True, if the expansion was successful, false otherwise
+ bool expandROT(SDNode *N, SDValue &Result, SelectionDAG &DAG) const;
+
/// Expand float(f32) to SINT(i64) conversion
/// \param N Node to expand
/// \param Result output after conversion
/// \returns True, if the expansion was successful, false otherwise
bool expandFP_TO_SINT(SDNode *N, SDValue &Result, SelectionDAG &DAG) const;
+ /// Expand float to UINT conversion
+ /// \param N Node to expand
+ /// \param Result output after conversion
+ /// \returns True, if the expansion was successful, false otherwise
+ bool expandFP_TO_UINT(SDNode *N, SDValue &Result, SelectionDAG &DAG) const;
+
+ /// Expand UINT(i64) to double(f64) conversion
+ /// \param N Node to expand
+ /// \param Result output after conversion
+ /// \returns True, if the expansion was successful, false otherwise
+ bool expandUINT_TO_FP(SDNode *N, SDValue &Result, SelectionDAG &DAG) const;
+
+ /// Expand fminnum/fmaxnum into fminnum_ieee/fmaxnum_ieee with quieted inputs.
+ SDValue expandFMINNUM_FMAXNUM(SDNode *N, SelectionDAG &DAG) const;
+
+ /// Expand CTPOP nodes. Expands vector/scalar CTPOP nodes,
+ /// vector nodes can only succeed if all operations are legal/custom.
+ /// \param N Node to expand
+ /// \param Result output after conversion
+ /// \returns True, if the expansion was successful, false otherwise
+ bool expandCTPOP(SDNode *N, SDValue &Result, SelectionDAG &DAG) const;
+
+ /// Expand CTLZ/CTLZ_ZERO_UNDEF nodes. Expands vector/scalar CTLZ nodes,
+ /// vector nodes can only succeed if all operations are legal/custom.
+ /// \param N Node to expand
+ /// \param Result output after conversion
+ /// \returns True, if the expansion was successful, false otherwise
+ bool expandCTLZ(SDNode *N, SDValue &Result, SelectionDAG &DAG) const;
+
+ /// Expand CTTZ/CTTZ_ZERO_UNDEF nodes. Expands vector/scalar CTTZ nodes,
+ /// vector nodes can only succeed if all operations are legal/custom.
+ /// \param N Node to expand
+ /// \param Result output after conversion
+ /// \returns True, if the expansion was successful, false otherwise
+ bool expandCTTZ(SDNode *N, SDValue &Result, SelectionDAG &DAG) const;
+
+ /// Expand ABS nodes. Expands vector/scalar ABS nodes,
+ /// vector nodes can only succeed if all operations are legal/custom.
+ /// (ABS x) -> (XOR (ADD x, (SRA x, type_size)), (SRA x, type_size))
+ /// \param N Node to expand
+ /// \param Result output after conversion
+ /// \returns True, if the expansion was successful, false otherwise
+ bool expandABS(SDNode *N, SDValue &Result, SelectionDAG &DAG) const;
+
/// Turn load of vector type into a load of the individual elements.
/// \param LD load to expand
/// \returns MERGE_VALUEs of the scalar loads with their chains.
@@ -3681,6 +3864,14 @@
SDValue getVectorElementPointer(SelectionDAG &DAG, SDValue VecPtr, EVT VecVT,
SDValue Index) const;
+ /// Method for building the DAG expansion of ISD::[US][ADD|SUB]SAT. This
+ /// method accepts integers as its arguments.
+ SDValue expandAddSubSat(SDNode *Node, SelectionDAG &DAG) const;
+
+ /// Method for building the DAG expansion of ISD::SMULFIX. This method accepts
+ /// integers as its arguments.
+ SDValue expandFixedPointMul(SDNode *Node, SelectionDAG &DAG) const;
+
//===--------------------------------------------------------------------===//
// Instruction Emitting Hooks
//
@@ -3732,9 +3923,10 @@
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,
diff --git a/linux-x64/clang/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/linux-x64/clang/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index f5c7fc8..a1fb81c 100644
--- a/linux-x64/clang/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -90,6 +89,8 @@
const MCExpr *lowerRelativeReference(const GlobalValue *LHS,
const GlobalValue *RHS,
const TargetMachine &TM) const override;
+
+ MCSection *getSectionForCommandLines() const override;
};
class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
diff --git a/linux-x64/clang/include/llvm/CodeGen/TargetOpcodes.h b/linux-x64/clang/include/llvm/CodeGen/TargetOpcodes.h
index d0d959c..080a244 100644
--- a/linux-x64/clang/include/llvm/CodeGen/TargetOpcodes.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/TargetPassConfig.h b/linux-x64/clang/include/llvm/CodeGen/TargetPassConfig.h
index 8f5c9cb..1def50d 100644
--- a/linux-x64/clang/include/llvm/CodeGen/TargetPassConfig.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -75,9 +74,6 @@
}
};
-template <> struct isPodLike<IdentifyingPassPtr> {
- static const bool value = true;
-};
/// Target-Independent Code Generator Pass Configuration Options.
///
@@ -90,6 +86,19 @@
AnalysisID StartAfter = nullptr;
AnalysisID StopBefore = nullptr;
AnalysisID StopAfter = nullptr;
+
+ unsigned StartBeforeInstanceNum = 0;
+ unsigned StartBeforeCount = 0;
+
+ unsigned StartAfterInstanceNum = 0;
+ unsigned StartAfterCount = 0;
+
+ unsigned StopBeforeInstanceNum = 0;
+ unsigned StopBeforeCount = 0;
+
+ unsigned StopAfterInstanceNum = 0;
+ unsigned StopAfterCount = 0;
+
bool Started = true;
bool Stopped = false;
bool AddingMachinePasses = false;
@@ -145,13 +154,13 @@
CodeGenOpt::Level getOptLevel() const;
- /// Describe the status of the codegen
- /// pipeline set by this target pass config.
- /// Having a limited codegen pipeline means that options
- /// have been used to restrict what codegen is doing.
- /// In particular, that means that codegen won't emit
- /// assembly code.
- bool hasLimitedCodeGenPipeline() const;
+ /// Returns true if one of the `-start-after`, `-start-before`, `-stop-after`
+ /// or `-stop-before` options is set.
+ static bool hasLimitedCodeGenPipeline();
+
+ /// Returns true if none of the `-stop-before` and `-stop-after` options is
+ /// set.
+ static bool willCompleteCodeGenPipeline();
/// If hasLimitedCodeGenPipeline is true, this method
/// returns a string with the name of the options, separated
@@ -159,13 +168,6 @@
std::string
getLimitedCodeGenPipelineReason(const char *Separator = "/") const;
- /// Check if the codegen pipeline is limited in such a way that it
- /// won't be complete. When the codegen pipeline is not complete,
- /// this means it may not be possible to generate assembly from it.
- bool willCompleteCodeGenPipeline() const {
- return !hasLimitedCodeGenPipeline() || (!StopAfter && !StopBefore);
- }
-
void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); }
bool getEnableTailMerge() const { return EnableTailMerge; }
@@ -313,6 +315,10 @@
/// 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;
+
protected:
// Helper to verify the analysis is really immutable.
void setOpt(bool &Opt, bool Val);
diff --git a/linux-x64/clang/include/llvm/CodeGen/TargetRegisterInfo.h b/linux-x64/clang/include/llvm/CodeGen/TargetRegisterInfo.h
index 0fbff31..5ed1e44 100644
--- a/linux-x64/clang/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/TargetSchedule.h b/linux-x64/clang/include/llvm/CodeGen/TargetSchedule.h
index 6173925..cce85c8 100644
--- a/linux-x64/clang/include/llvm/CodeGen/TargetSchedule.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/TargetSubtargetInfo.h b/linux-x64/clang/include/llvm/CodeGen/TargetSubtargetInfo.h
index e28673d..bf0e9b2 100644
--- a/linux-x64/clang/include/llvm/CodeGen/TargetSubtargetInfo.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -169,6 +168,19 @@
return isZeroIdiom(MI, Mask);
}
+ /// Returns true if MI is a candidate for move elimination.
+ ///
+ /// A candidate for move elimination may be optimized out at register renaming
+ /// stage. Subtargets can specify the set of optimizable moves by
+ /// instantiating tablegen class `IsOptimizableRegisterMove` (see
+ /// llvm/Target/TargetInstrPredicate.td).
+ ///
+ /// SubtargetEmitter is responsible for processing all the definitions of class
+ /// IsOptimizableRegisterMove, and auto-generate an override for this method.
+ virtual bool isOptimizableRegisterMove(const MachineInstr *MI) const {
+ return false;
+ }
+
/// True if the subtarget should run MachineScheduler after aggressive
/// coalescing.
///
@@ -177,9 +189,6 @@
/// 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; }
@@ -273,10 +282,6 @@
/// 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;
};
diff --git a/linux-x64/clang/include/llvm/CodeGen/UnreachableBlockElim.h b/linux-x64/clang/include/llvm/CodeGen/UnreachableBlockElim.h
index 3e7afd4..d52d7c3 100644
--- a/linux-x64/clang/include/llvm/CodeGen/UnreachableBlockElim.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/ValueTypes.h b/linux-x64/clang/include/llvm/CodeGen/ValueTypes.h
index d2ef4a9..c540c94 100644
--- a/linux-x64/clang/include/llvm/CodeGen/ValueTypes.h
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/CodeGen/ValueTypes.td b/linux-x64/clang/include/llvm/CodeGen/ValueTypes.td
index 0abb4ec..f82faf2 100644
--- a/linux-x64/clang/include/llvm/CodeGen/ValueTypes.td
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/VirtRegMap.h b/linux-x64/clang/include/llvm/CodeGen/VirtRegMap.h
index 6a8e50a..7bdecbe 100644
--- a/linux-x64/clang/include/llvm/CodeGen/VirtRegMap.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
diff --git a/linux-x64/clang/include/llvm/CodeGen/WasmEHFuncInfo.h b/linux-x64/clang/include/llvm/CodeGen/WasmEHFuncInfo.h
index aa97934..aaca847 100644
--- a/linux-x64/clang/include/llvm/CodeGen/WasmEHFuncInfo.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//
@@ -21,6 +20,8 @@
namespace llvm {
+enum EventTag { CPP_EXCEPTION = 0, C_LONGJMP = 1 };
+
using BBOrMBB = PointerUnion<const BasicBlock *, MachineBasicBlock *>;
struct WasmEHFuncInfo {
diff --git a/linux-x64/clang/include/llvm/CodeGen/WinEHFuncInfo.h b/linux-x64/clang/include/llvm/CodeGen/WinEHFuncInfo.h
index 8043024..f098316 100644
--- a/linux-x64/clang/include/llvm/CodeGen/WinEHFuncInfo.h
+++ b/linux-x64/clang/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
//
//===----------------------------------------------------------------------===//
//