Vendor import of llvm-project branch release/14.x llvmorg-14.0.5-0-gc12386ae247c.
This commit is contained in:
@@ -6124,9 +6124,6 @@ static bool HandleFunctionCall(SourceLocation CallLoc,
|
||||
if (!handleTrivialCopy(Info, MD->getParamDecl(0), Args[0], RHSValue,
|
||||
MD->getParent()->isUnion()))
|
||||
return false;
|
||||
if (Info.getLangOpts().CPlusPlus20 && MD->isTrivial() &&
|
||||
!HandleUnionActiveMemberChange(Info, Args[0], *This))
|
||||
return false;
|
||||
if (!handleAssignment(Info, Args[0], *This, MD->getThisType(),
|
||||
RHSValue))
|
||||
return false;
|
||||
@@ -7638,6 +7635,15 @@ class ExprEvaluatorBase
|
||||
if (!EvaluateObjectArgument(Info, Args[0], ThisVal))
|
||||
return false;
|
||||
This = &ThisVal;
|
||||
|
||||
// If this is syntactically a simple assignment using a trivial
|
||||
// assignment operator, start the lifetimes of union members as needed,
|
||||
// per C++20 [class.union]5.
|
||||
if (Info.getLangOpts().CPlusPlus20 && OCE &&
|
||||
OCE->getOperator() == OO_Equal && MD->isTrivial() &&
|
||||
!HandleUnionActiveMemberChange(Info, Args[0], ThisVal))
|
||||
return false;
|
||||
|
||||
Args = Args.slice(1);
|
||||
} else if (MD && MD->isLambdaStaticInvoker()) {
|
||||
// Map the static invoker for the lambda back to the call operator.
|
||||
|
||||
@@ -24,7 +24,8 @@ namespace targets {
|
||||
struct LLVM_LIBRARY_VISIBILITY MCUInfo {
|
||||
const char *Name;
|
||||
const char *DefineName;
|
||||
const int NumFlashBanks; // -1 means the device does not support LPM/ELPM.
|
||||
const int NumFlashBanks; // Set to 0 for the devices do not support LPM/ELPM.
|
||||
bool IsTiny; // Set to true for the devices belong to the avrtiny family.
|
||||
};
|
||||
|
||||
// This list should be kept up-to-date with AVRDevices.td in LLVM.
|
||||
@@ -267,14 +268,14 @@ static MCUInfo AVRMcus[] = {
|
||||
{"atxmega128a1", "__AVR_ATxmega128A1__", 2},
|
||||
{"atxmega128a1u", "__AVR_ATxmega128A1U__", 2},
|
||||
{"atxmega128a4u", "__AVR_ATxmega128A4U__", 2},
|
||||
{"attiny4", "__AVR_ATtiny4__", 0},
|
||||
{"attiny5", "__AVR_ATtiny5__", 0},
|
||||
{"attiny9", "__AVR_ATtiny9__", 0},
|
||||
{"attiny10", "__AVR_ATtiny10__", 0},
|
||||
{"attiny20", "__AVR_ATtiny20__", 0},
|
||||
{"attiny40", "__AVR_ATtiny40__", 0},
|
||||
{"attiny102", "__AVR_ATtiny102__", 0},
|
||||
{"attiny104", "__AVR_ATtiny104__", 0},
|
||||
{"attiny4", "__AVR_ATtiny4__", 0, true},
|
||||
{"attiny5", "__AVR_ATtiny5__", 0, true},
|
||||
{"attiny9", "__AVR_ATtiny9__", 0, true},
|
||||
{"attiny10", "__AVR_ATtiny10__", 0, true},
|
||||
{"attiny20", "__AVR_ATtiny20__", 0, true},
|
||||
{"attiny40", "__AVR_ATtiny40__", 0, true},
|
||||
{"attiny102", "__AVR_ATtiny102__", 0, true},
|
||||
{"attiny104", "__AVR_ATtiny104__", 0, true},
|
||||
{"attiny202", "__AVR_ATtiny202__", 1},
|
||||
{"attiny402", "__AVR_ATtiny402__", 1},
|
||||
{"attiny204", "__AVR_ATtiny204__", 1},
|
||||
@@ -325,6 +326,27 @@ void AVRTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
|
||||
Values.push_back(Info.Name);
|
||||
}
|
||||
|
||||
bool AVRTargetInfo::setCPU(const std::string &Name) {
|
||||
// Set the ABI and CPU fields if parameter Name is a family name.
|
||||
if (llvm::is_contained(ValidFamilyNames, Name)) {
|
||||
CPU = Name;
|
||||
ABI = Name == "avrtiny" ? "avrtiny" : "avr";
|
||||
return true;
|
||||
}
|
||||
|
||||
// Set the ABI field if parameter Name is a device name.
|
||||
auto It = llvm::find_if(
|
||||
AVRMcus, [&](const MCUInfo &Info) { return Info.Name == Name; });
|
||||
if (It != std::end(AVRMcus)) {
|
||||
CPU = Name;
|
||||
ABI = It->IsTiny ? "avrtiny" : "avr";
|
||||
return true;
|
||||
}
|
||||
|
||||
// Parameter Name is neither valid family name nor valid device name.
|
||||
return false;
|
||||
}
|
||||
|
||||
void AVRTargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const {
|
||||
Builder.defineMacro("AVR");
|
||||
|
||||
@@ -74,8 +74,7 @@ class LLVM_LIBRARY_VISIBILITY AVRTargetInfo : public TargetInfo {
|
||||
static const char *const GCCRegNames[] = {
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
|
||||
"r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
|
||||
"r20", "r21", "r22", "r23", "r24", "r25", "X", "Y", "Z", "SP"
|
||||
};
|
||||
"r20", "r21", "r22", "r23", "r24", "r25", "X", "Y", "Z", "SP"};
|
||||
return llvm::makeArrayRef(GCCRegNames);
|
||||
}
|
||||
|
||||
@@ -169,15 +168,12 @@ class LLVM_LIBRARY_VISIBILITY AVRTargetInfo : public TargetInfo {
|
||||
|
||||
bool isValidCPUName(StringRef Name) const override;
|
||||
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
|
||||
bool setCPU(const std::string &Name) override {
|
||||
bool isValid = isValidCPUName(Name);
|
||||
if (isValid)
|
||||
CPU = Name;
|
||||
return isValid;
|
||||
}
|
||||
bool setCPU(const std::string &Name) override;
|
||||
StringRef getABI() const override { return ABI; }
|
||||
|
||||
protected:
|
||||
std::string CPU;
|
||||
StringRef ABI;
|
||||
};
|
||||
|
||||
} // namespace targets
|
||||
|
||||
@@ -9,10 +9,11 @@
|
||||
#ifndef LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H
|
||||
#define LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H
|
||||
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "Address.h"
|
||||
#include "CodeGenTypeCache.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
|
||||
namespace clang {
|
||||
namespace CodeGen {
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "llvm/IR/InlineAsm.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/Transforms/Utils/Local.h"
|
||||
using namespace clang;
|
||||
using namespace CodeGen;
|
||||
@@ -1056,10 +1057,19 @@ void CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
|
||||
// Call EmitStoreOfScalar except when the lvalue is a bitfield to emit a
|
||||
// primitive store.
|
||||
assert(isa<NoExpansion>(Exp.get()));
|
||||
if (LV.isBitField())
|
||||
EmitStoreThroughLValue(RValue::get(&*AI++), LV);
|
||||
else
|
||||
EmitStoreOfScalar(&*AI++, LV);
|
||||
llvm::Value *Arg = &*AI++;
|
||||
if (LV.isBitField()) {
|
||||
EmitStoreThroughLValue(RValue::get(Arg), LV);
|
||||
} else {
|
||||
// TODO: currently there are some places are inconsistent in what LLVM
|
||||
// pointer type they use (see D118744). Once clang uses opaque pointers
|
||||
// all LLVM pointer types will be the same and we can remove this check.
|
||||
if (Arg->getType()->isPointerTy()) {
|
||||
Address Addr = LV.getAddress(*this);
|
||||
Arg = Builder.CreateBitCast(Arg, Addr.getElementType());
|
||||
}
|
||||
EmitStoreOfScalar(Arg, LV);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,9 +25,20 @@
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace CodeGen;
|
||||
|
||||
#ifndef NDEBUG
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
// TODO: turn on by default when defined(EXPENSIVE_CHECKS) once check-clang is
|
||||
// -verify-type-cache clean.
|
||||
static llvm::cl::opt<bool> VerifyTypeCache(
|
||||
"verify-type-cache",
|
||||
llvm::cl::desc("Verify that the type cache matches the computed type"),
|
||||
llvm::cl::init(false), llvm::cl::Hidden);
|
||||
#endif
|
||||
|
||||
CodeGenTypes::CodeGenTypes(CodeGenModule &cgm)
|
||||
: CGM(cgm), Context(cgm.getContext()), TheModule(cgm.getModule()),
|
||||
Target(cgm.getTarget()), TheCXXABI(cgm.getCXXABI()),
|
||||
@@ -382,9 +393,6 @@ llvm::Type *CodeGenTypes::ConvertFunctionTypeInternal(QualType QFT) {
|
||||
|
||||
RecordsBeingLaidOut.erase(Ty);
|
||||
|
||||
if (SkippedLayout)
|
||||
TypeCache.clear();
|
||||
|
||||
if (RecordsBeingLaidOut.empty())
|
||||
while (!DeferredRecords.empty())
|
||||
ConvertRecordDeclType(DeferredRecords.pop_back_val());
|
||||
@@ -415,11 +423,29 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
|
||||
if (const RecordType *RT = dyn_cast<RecordType>(Ty))
|
||||
return ConvertRecordDeclType(RT->getDecl());
|
||||
|
||||
// See if type is already cached.
|
||||
llvm::DenseMap<const Type *, llvm::Type *>::iterator TCI = TypeCache.find(Ty);
|
||||
// If type is found in map then use it. Otherwise, convert type T.
|
||||
if (TCI != TypeCache.end())
|
||||
return TCI->second;
|
||||
// The LLVM type we return for a given Clang type may not always be the same,
|
||||
// most notably when dealing with recursive structs. We mark these potential
|
||||
// cases with ShouldUseCache below. Builtin types cannot be recursive.
|
||||
// TODO: when clang uses LLVM opaque pointers we won't be able to represent
|
||||
// recursive types with LLVM types, making this logic much simpler.
|
||||
llvm::Type *CachedType = nullptr;
|
||||
bool ShouldUseCache =
|
||||
Ty->isBuiltinType() ||
|
||||
(noRecordsBeingLaidOut() && FunctionsBeingProcessed.empty());
|
||||
if (ShouldUseCache) {
|
||||
llvm::DenseMap<const Type *, llvm::Type *>::iterator TCI =
|
||||
TypeCache.find(Ty);
|
||||
if (TCI != TypeCache.end())
|
||||
CachedType = TCI->second;
|
||||
if (CachedType) {
|
||||
#ifndef NDEBUG
|
||||
if (!VerifyTypeCache)
|
||||
return CachedType;
|
||||
#else
|
||||
return CachedType;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// If we don't have it in the cache, convert it now.
|
||||
llvm::Type *ResultType = nullptr;
|
||||
@@ -797,7 +823,15 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
|
||||
|
||||
assert(ResultType && "Didn't convert a type?");
|
||||
|
||||
TypeCache[Ty] = ResultType;
|
||||
#ifndef NDEBUG
|
||||
if (CachedType) {
|
||||
assert(CachedType == ResultType &&
|
||||
"Cached type doesn't match computed type");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ShouldUseCache)
|
||||
TypeCache[Ty] = ResultType;
|
||||
return ResultType;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
#include "CodeGenFunction.h"
|
||||
#include "clang/AST/Attr.h"
|
||||
#include "clang/AST/RecordLayout.h"
|
||||
#include "clang/Basic/Builtins.h"
|
||||
#include "clang/Basic/CodeGenOptions.h"
|
||||
#include "clang/Basic/DiagnosticFrontend.h"
|
||||
#include "clang/Basic/Builtins.h"
|
||||
#include "clang/CodeGen/CGFunctionInfo.h"
|
||||
#include "clang/CodeGen/SwiftCallingConv.h"
|
||||
#include "llvm/ADT/SmallBitVector.h"
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "llvm/IR/IntrinsicsNVPTX.h"
|
||||
#include "llvm/IR/IntrinsicsS390.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm> // std::sort
|
||||
|
||||
@@ -8272,32 +8273,93 @@ void M68kTargetCodeGenInfo::setTargetAttributes(
|
||||
|
||||
namespace {
|
||||
class AVRABIInfo : public DefaultABIInfo {
|
||||
public:
|
||||
AVRABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
|
||||
private:
|
||||
// The total amount of registers can be used to pass parameters. It is 18 on
|
||||
// AVR, or 6 on AVRTiny.
|
||||
const unsigned ParamRegs;
|
||||
// The total amount of registers can be used to pass return value. It is 8 on
|
||||
// AVR, or 4 on AVRTiny.
|
||||
const unsigned RetRegs;
|
||||
|
||||
ABIArgInfo classifyReturnType(QualType Ty) const {
|
||||
// A return struct with size less than or equal to 8 bytes is returned
|
||||
// directly via registers R18-R25.
|
||||
if (isAggregateTypeForABI(Ty) && getContext().getTypeSize(Ty) <= 64)
|
||||
return ABIArgInfo::getDirect();
|
||||
else
|
||||
return DefaultABIInfo::classifyReturnType(Ty);
|
||||
public:
|
||||
AVRABIInfo(CodeGenTypes &CGT, unsigned NPR, unsigned NRR)
|
||||
: DefaultABIInfo(CGT), ParamRegs(NPR), RetRegs(NRR) {}
|
||||
|
||||
ABIArgInfo classifyReturnType(QualType Ty, bool &LargeRet) const {
|
||||
if (isAggregateTypeForABI(Ty)) {
|
||||
// On AVR, a return struct with size less than or equals to 8 bytes is
|
||||
// returned directly via registers R18-R25. On AVRTiny, a return struct
|
||||
// with size less than or equals to 4 bytes is returned directly via
|
||||
// registers R22-R25.
|
||||
if (getContext().getTypeSize(Ty) <= RetRegs * 8)
|
||||
return ABIArgInfo::getDirect();
|
||||
// A return struct with larger size is returned via a stack
|
||||
// slot, along with a pointer to it as the function's implicit argument.
|
||||
LargeRet = true;
|
||||
return getNaturalAlignIndirect(Ty);
|
||||
}
|
||||
// Otherwise we follow the default way which is compatible.
|
||||
return DefaultABIInfo::classifyReturnType(Ty);
|
||||
}
|
||||
|
||||
ABIArgInfo classifyArgumentType(QualType Ty, unsigned &NumRegs) const {
|
||||
unsigned TySize = getContext().getTypeSize(Ty);
|
||||
|
||||
// An int8 type argument always costs two registers like an int16.
|
||||
if (TySize == 8 && NumRegs >= 2) {
|
||||
NumRegs -= 2;
|
||||
return ABIArgInfo::getExtend(Ty);
|
||||
}
|
||||
|
||||
// If the argument size is an odd number of bytes, round up the size
|
||||
// to the next even number.
|
||||
TySize = llvm::alignTo(TySize, 16);
|
||||
|
||||
// Any type including an array/struct type can be passed in rgisters,
|
||||
// if there are enough registers left.
|
||||
if (TySize <= NumRegs * 8) {
|
||||
NumRegs -= TySize / 8;
|
||||
return ABIArgInfo::getDirect();
|
||||
}
|
||||
|
||||
// An argument is passed either completely in registers or completely in
|
||||
// memory. Since there are not enough registers left, current argument
|
||||
// and all other unprocessed arguments should be passed in memory.
|
||||
// However we still need to return `ABIArgInfo::getDirect()` other than
|
||||
// `ABIInfo::getNaturalAlignIndirect(Ty)`, otherwise an extra stack slot
|
||||
// will be allocated, so the stack frame layout will be incompatible with
|
||||
// avr-gcc.
|
||||
NumRegs = 0;
|
||||
return ABIArgInfo::getDirect();
|
||||
}
|
||||
|
||||
// Just copy the original implementation of DefaultABIInfo::computeInfo(),
|
||||
// since DefaultABIInfo::classify{Return,Argument}Type() are not virtual.
|
||||
void computeInfo(CGFunctionInfo &FI) const override {
|
||||
// Decide the return type.
|
||||
bool LargeRet = false;
|
||||
if (!getCXXABI().classifyReturnType(FI))
|
||||
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
|
||||
FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), LargeRet);
|
||||
|
||||
// Decide each argument type. The total number of registers can be used for
|
||||
// arguments depends on several factors:
|
||||
// 1. Arguments of varargs functions are passed on the stack. This applies
|
||||
// even to the named arguments. So no register can be used.
|
||||
// 2. Total 18 registers can be used on avr and 6 ones on avrtiny.
|
||||
// 3. If the return type is a struct with too large size, two registers
|
||||
// (out of 18/6) will be cost as an implicit pointer argument.
|
||||
unsigned NumRegs = ParamRegs;
|
||||
if (FI.isVariadic())
|
||||
NumRegs = 0;
|
||||
else if (LargeRet)
|
||||
NumRegs -= 2;
|
||||
for (auto &I : FI.arguments())
|
||||
I.info = classifyArgumentType(I.type);
|
||||
I.info = classifyArgumentType(I.type, NumRegs);
|
||||
}
|
||||
};
|
||||
|
||||
class AVRTargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
public:
|
||||
AVRTargetCodeGenInfo(CodeGenTypes &CGT)
|
||||
: TargetCodeGenInfo(std::make_unique<AVRABIInfo>(CGT)) {}
|
||||
AVRTargetCodeGenInfo(CodeGenTypes &CGT, unsigned NPR, unsigned NRR)
|
||||
: TargetCodeGenInfo(std::make_unique<AVRABIInfo>(CGT, NPR, NRR)) {}
|
||||
|
||||
LangAS getGlobalVarAddressSpace(CodeGenModule &CGM,
|
||||
const VarDecl *D) const override {
|
||||
@@ -11270,8 +11332,14 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
|
||||
case llvm::Triple::mips64el:
|
||||
return SetCGInfo(new MIPSTargetCodeGenInfo(Types, false));
|
||||
|
||||
case llvm::Triple::avr:
|
||||
return SetCGInfo(new AVRTargetCodeGenInfo(Types));
|
||||
case llvm::Triple::avr: {
|
||||
// For passing parameters, R8~R25 are used on avr, and R18~R25 are used
|
||||
// on avrtiny. For passing return value, R18~R25 are used on avr, and
|
||||
// R22~R25 are used on avrtiny.
|
||||
unsigned NPR = getTarget().getABI() == "avrtiny" ? 6 : 18;
|
||||
unsigned NRR = getTarget().getABI() == "avrtiny" ? 4 : 8;
|
||||
return SetCGInfo(new AVRTargetCodeGenInfo(Types, NPR, NRR));
|
||||
}
|
||||
|
||||
case llvm::Triple::aarch64:
|
||||
case llvm::Triple::aarch64_32:
|
||||
|
||||
@@ -753,6 +753,7 @@ BreakableLineCommentSection::BreakableLineCommentSection(
|
||||
assert(Tok.is(TT_LineComment) &&
|
||||
"line comment section must start with a line comment");
|
||||
FormatToken *LineTok = nullptr;
|
||||
const int Minimum = Style.SpacesInLineCommentPrefix.Minimum;
|
||||
// How many spaces we changed in the first line of the section, this will be
|
||||
// applied in all following lines
|
||||
int FirstLineSpaceChange = 0;
|
||||
@@ -775,7 +776,7 @@ BreakableLineCommentSection::BreakableLineCommentSection(
|
||||
Lines[i] = Lines[i].ltrim(Blanks);
|
||||
StringRef IndentPrefix = getLineCommentIndentPrefix(Lines[i], Style);
|
||||
OriginalPrefix[i] = IndentPrefix;
|
||||
const unsigned SpacesInPrefix = llvm::count(IndentPrefix, ' ');
|
||||
const int SpacesInPrefix = llvm::count(IndentPrefix, ' ');
|
||||
|
||||
// On the first line of the comment section we calculate how many spaces
|
||||
// are to be added or removed, all lines after that just get only the
|
||||
@@ -784,12 +785,11 @@ BreakableLineCommentSection::BreakableLineCommentSection(
|
||||
// e.g. from "///" to "//".
|
||||
if (i == 0 || OriginalPrefix[i].rtrim(Blanks) !=
|
||||
OriginalPrefix[i - 1].rtrim(Blanks)) {
|
||||
if (SpacesInPrefix < Style.SpacesInLineCommentPrefix.Minimum &&
|
||||
Lines[i].size() > IndentPrefix.size() &&
|
||||
if (SpacesInPrefix < Minimum && Lines[i].size() > IndentPrefix.size() &&
|
||||
isAlphanumeric(Lines[i][IndentPrefix.size()])) {
|
||||
FirstLineSpaceChange =
|
||||
Style.SpacesInLineCommentPrefix.Minimum - SpacesInPrefix;
|
||||
} else if (SpacesInPrefix > Style.SpacesInLineCommentPrefix.Maximum) {
|
||||
FirstLineSpaceChange = Minimum - SpacesInPrefix;
|
||||
} else if (static_cast<unsigned>(SpacesInPrefix) >
|
||||
Style.SpacesInLineCommentPrefix.Maximum) {
|
||||
FirstLineSpaceChange =
|
||||
Style.SpacesInLineCommentPrefix.Maximum - SpacesInPrefix;
|
||||
} else {
|
||||
@@ -800,10 +800,9 @@ BreakableLineCommentSection::BreakableLineCommentSection(
|
||||
if (Lines[i].size() != IndentPrefix.size()) {
|
||||
PrefixSpaceChange[i] = FirstLineSpaceChange;
|
||||
|
||||
if (SpacesInPrefix + PrefixSpaceChange[i] <
|
||||
Style.SpacesInLineCommentPrefix.Minimum) {
|
||||
PrefixSpaceChange[i] += Style.SpacesInLineCommentPrefix.Minimum -
|
||||
(SpacesInPrefix + PrefixSpaceChange[i]);
|
||||
if (SpacesInPrefix + PrefixSpaceChange[i] < Minimum) {
|
||||
PrefixSpaceChange[i] +=
|
||||
Minimum - (SpacesInPrefix + PrefixSpaceChange[i]);
|
||||
}
|
||||
|
||||
assert(Lines[i].size() > IndentPrefix.size());
|
||||
|
||||
@@ -414,6 +414,7 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
|
||||
--Previous) {
|
||||
Changes[Previous + 1].Spaces -= Shift;
|
||||
Changes[Previous].Spaces += Shift;
|
||||
Changes[Previous].StartOfTokenColumn += Shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,7 +509,7 @@ __device__ inline void *__nv_cvta_constant_to_generic_impl(size_t __ptr) {
|
||||
__device__ inline void *__nv_cvta_local_to_generic_impl(size_t __ptr) {
|
||||
return (void *)(void __attribute__((address_space(5))) *)__ptr;
|
||||
}
|
||||
__device__ inline uint32_t __nvvm_get_smem_pointer(void *__ptr) {
|
||||
__device__ inline cuuint32_t __nvvm_get_smem_pointer(void *__ptr) {
|
||||
return __nv_cvta_generic_to_shared_impl(__ptr);
|
||||
}
|
||||
} // extern "C"
|
||||
|
||||
@@ -13314,11 +13314,11 @@ StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
|
||||
if (!EndOfTile.isUsable())
|
||||
return StmtError();
|
||||
ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
|
||||
BO_LE, MakeInnerRef(), EndOfTile.get());
|
||||
BO_LT, MakeInnerRef(), EndOfTile.get());
|
||||
if (!InnerCond1.isUsable())
|
||||
return StmtError();
|
||||
ExprResult InnerCond2 =
|
||||
BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LE, MakeInnerRef(),
|
||||
BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeInnerRef(),
|
||||
MakeNumIterations());
|
||||
if (!InnerCond2.isUsable())
|
||||
return StmtError();
|
||||
|
||||
@@ -108,7 +108,7 @@ static const NoteTag *getNoteTag(CheckerContext &C,
|
||||
bool CastSucceeds, bool IsKnownCast) {
|
||||
std::string CastToName =
|
||||
CastInfo ? CastInfo->to()->getAsCXXRecordDecl()->getNameAsString()
|
||||
: CastToTy->getPointeeCXXRecordDecl()->getNameAsString();
|
||||
: CastToTy.getAsString();
|
||||
Object = Object->IgnoreParenImpCasts();
|
||||
|
||||
return C.getNoteTag(
|
||||
@@ -163,9 +163,9 @@ static const NoteTag *getNoteTag(CheckerContext &C,
|
||||
bool First = true;
|
||||
for (QualType CastToTy: CastToTyVec) {
|
||||
std::string CastToName =
|
||||
CastToTy->getAsCXXRecordDecl() ?
|
||||
CastToTy->getAsCXXRecordDecl()->getNameAsString() :
|
||||
CastToTy->getPointeeCXXRecordDecl()->getNameAsString();
|
||||
CastToTy->getAsCXXRecordDecl()
|
||||
? CastToTy->getAsCXXRecordDecl()->getNameAsString()
|
||||
: CastToTy.getAsString();
|
||||
Out << ' ' << ((CastToTyVec.size() == 1) ? "not" :
|
||||
(First ? "neither" : "nor")) << " a '" << CastToName
|
||||
<< '\'';
|
||||
|
||||
@@ -363,6 +363,9 @@ OPTIMISED_CASES
|
||||
#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, xor, ^)
|
||||
OPTIMISED_CASES
|
||||
#undef OPTIMISED_CASE
|
||||
// Allow build with clang without __c11_atomic_fetch_nand builtin (pre-14)
|
||||
#if __has_builtin(__c11_atomic_fetch_nand)
|
||||
#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW_NAND(n, lockfree, type)
|
||||
OPTIMISED_CASES
|
||||
#undef OPTIMISED_CASE
|
||||
#endif
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#ifndef LLVM_SUPPORT_BASE64_H
|
||||
#define LLVM_SUPPORT_BASE64_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#ifndef LLVM_SUPPORT_SIGNALS_H
|
||||
#define LLVM_SUPPORT_SIGNALS_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -52,6 +52,8 @@ static MCSubtargetInfo *
|
||||
createAArch64MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
|
||||
if (CPU.empty()) {
|
||||
CPU = "generic";
|
||||
if (FS.empty())
|
||||
FS = "+v8a";
|
||||
|
||||
if (TT.isArm64e())
|
||||
CPU = "apple-a12";
|
||||
|
||||
@@ -1290,7 +1290,8 @@ InstructionCost ARMTTIImpl::getShuffleCost(TTI::ShuffleKind Kind,
|
||||
|
||||
if (!Mask.empty()) {
|
||||
std::pair<InstructionCost, MVT> LT = TLI->getTypeLegalizationCost(DL, Tp);
|
||||
if (Mask.size() <= LT.second.getVectorNumElements() &&
|
||||
if (LT.second.isVector() &&
|
||||
Mask.size() <= LT.second.getVectorNumElements() &&
|
||||
(isVREVMask(Mask, LT.second, 16) || isVREVMask(Mask, LT.second, 32) ||
|
||||
isVREVMask(Mask, LT.second, 64)))
|
||||
return ST->getMVEVectorCostFactor(TTI::TCK_RecipThroughput) * LT.first;
|
||||
|
||||
@@ -192,6 +192,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
case MipsISD::Ret: return "MipsISD::Ret";
|
||||
case MipsISD::ERet: return "MipsISD::ERet";
|
||||
case MipsISD::EH_RETURN: return "MipsISD::EH_RETURN";
|
||||
case MipsISD::FAbs: return "MipsISD::FAbs";
|
||||
case MipsISD::FMS: return "MipsISD::FMS";
|
||||
case MipsISD::FPBrcond: return "MipsISD::FPBrcond";
|
||||
case MipsISD::FPCmp: return "MipsISD::FPCmp";
|
||||
@@ -353,15 +354,12 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
|
||||
setOperationAction(ISD::SETCC, MVT::f32, Custom);
|
||||
setOperationAction(ISD::SETCC, MVT::f64, Custom);
|
||||
setOperationAction(ISD::BRCOND, MVT::Other, Custom);
|
||||
setOperationAction(ISD::FABS, MVT::f32, Custom);
|
||||
setOperationAction(ISD::FABS, MVT::f64, Custom);
|
||||
setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom);
|
||||
setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom);
|
||||
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
|
||||
|
||||
if (!(TM.Options.NoNaNsFPMath || Subtarget.inAbs2008Mode())) {
|
||||
setOperationAction(ISD::FABS, MVT::f32, Custom);
|
||||
setOperationAction(ISD::FABS, MVT::f64, Custom);
|
||||
}
|
||||
|
||||
if (Subtarget.isGP64bit()) {
|
||||
setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
|
||||
setOperationAction(ISD::BlockAddress, MVT::i64, Custom);
|
||||
@@ -2421,11 +2419,14 @@ MipsTargetLowering::lowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const {
|
||||
return lowerFCOPYSIGN32(Op, DAG, Subtarget.hasExtractInsert());
|
||||
}
|
||||
|
||||
static SDValue lowerFABS32(SDValue Op, SelectionDAG &DAG,
|
||||
bool HasExtractInsert) {
|
||||
SDValue MipsTargetLowering::lowerFABS32(SDValue Op, SelectionDAG &DAG,
|
||||
bool HasExtractInsert) const {
|
||||
SDLoc DL(Op);
|
||||
SDValue Res, Const1 = DAG.getConstant(1, DL, MVT::i32);
|
||||
|
||||
if (DAG.getTarget().Options.NoNaNsFPMath || Subtarget.inAbs2008Mode())
|
||||
return DAG.getNode(MipsISD::FAbs, DL, Op.getValueType(), Op.getOperand(0));
|
||||
|
||||
// If operand is of type f64, extract the upper 32-bit. Otherwise, bitcast it
|
||||
// to i32.
|
||||
SDValue X = (Op.getValueType() == MVT::f32)
|
||||
@@ -2458,11 +2459,14 @@ static SDValue lowerFABS32(SDValue Op, SelectionDAG &DAG,
|
||||
return DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, LowX, Res);
|
||||
}
|
||||
|
||||
static SDValue lowerFABS64(SDValue Op, SelectionDAG &DAG,
|
||||
bool HasExtractInsert) {
|
||||
SDValue MipsTargetLowering::lowerFABS64(SDValue Op, SelectionDAG &DAG,
|
||||
bool HasExtractInsert) const {
|
||||
SDLoc DL(Op);
|
||||
SDValue Res, Const1 = DAG.getConstant(1, DL, MVT::i32);
|
||||
|
||||
if (DAG.getTarget().Options.NoNaNsFPMath || Subtarget.inAbs2008Mode())
|
||||
return DAG.getNode(MipsISD::FAbs, DL, Op.getValueType(), Op.getOperand(0));
|
||||
|
||||
// Bitcast to integer node.
|
||||
SDValue X = DAG.getNode(ISD::BITCAST, DL, MVT::i64, Op.getOperand(0));
|
||||
|
||||
|
||||
@@ -99,6 +99,9 @@ class TargetRegisterClass;
|
||||
// Floating Point Compare
|
||||
FPCmp,
|
||||
|
||||
// Floating point Abs
|
||||
FAbs,
|
||||
|
||||
// Floating point select
|
||||
FSELECT,
|
||||
|
||||
@@ -540,6 +543,10 @@ class TargetRegisterClass;
|
||||
SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerFABS(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerFABS32(SDValue Op, SelectionDAG &DAG,
|
||||
bool HasExtractInsert) const;
|
||||
SDValue lowerFABS64(SDValue Op, SelectionDAG &DAG,
|
||||
bool HasExtractInsert) const;
|
||||
SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
||||
@@ -956,6 +956,38 @@ bool MipsSEDAGToDAGISel::trySelect(SDNode *Node) {
|
||||
break;
|
||||
}
|
||||
|
||||
case MipsISD::FAbs: {
|
||||
MVT ResTy = Node->getSimpleValueType(0);
|
||||
assert((ResTy == MVT::f64 || ResTy == MVT::f32) &&
|
||||
"Unsupported float type!");
|
||||
unsigned Opc = 0;
|
||||
if (ResTy == MVT::f64)
|
||||
Opc = (Subtarget->isFP64bit() ? Mips::FABS_D64 : Mips::FABS_D32);
|
||||
else
|
||||
Opc = Mips::FABS_S;
|
||||
|
||||
if (Subtarget->inMicroMipsMode()) {
|
||||
switch (Opc) {
|
||||
case Mips::FABS_D64:
|
||||
Opc = Mips::FABS_D64_MM;
|
||||
break;
|
||||
case Mips::FABS_D32:
|
||||
Opc = Mips::FABS_D32_MM;
|
||||
break;
|
||||
case Mips::FABS_S:
|
||||
Opc = Mips::FABS_S_MM;
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unknown opcode for MIPS floating point abs!");
|
||||
}
|
||||
}
|
||||
|
||||
ReplaceNode(Node,
|
||||
CurDAG->getMachineNode(Opc, DL, ResTy, Node->getOperand(0)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Manually match MipsISD::Ins nodes to get the correct instruction. It has
|
||||
// to be done in this fashion so that we respect the differences between
|
||||
// dins and dinsm, as the difference is that the size operand has the range
|
||||
|
||||
@@ -491,15 +491,13 @@ bool PPCTTIImpl::mightUseCTR(BasicBlock *BB, TargetLibraryInfo *LibInfo,
|
||||
case Intrinsic::experimental_constrained_sin:
|
||||
case Intrinsic::experimental_constrained_cos:
|
||||
return true;
|
||||
// There is no corresponding FMA instruction for PPC double double.
|
||||
// Thus, we need to disable CTR loop generation for this type.
|
||||
case Intrinsic::fmuladd:
|
||||
case Intrinsic::copysign:
|
||||
if (CI->getArgOperand(0)->getType()->getScalarType()->
|
||||
isPPC_FP128Ty())
|
||||
return true;
|
||||
else
|
||||
continue; // ISD::FCOPYSIGN is never a library call.
|
||||
case Intrinsic::fmuladd:
|
||||
case Intrinsic::fma: Opcode = ISD::FMA; break;
|
||||
case Intrinsic::sqrt: Opcode = ISD::FSQRT; break;
|
||||
case Intrinsic::floor: Opcode = ISD::FFLOOR; break;
|
||||
|
||||
@@ -1173,6 +1173,8 @@ bool LoopIdiomRecognize::processLoopStridedStore(
|
||||
CallInst *NewCall;
|
||||
if (SplatValue) {
|
||||
AAMDNodes AATags = TheStore->getAAMetadata();
|
||||
for (Instruction *Store : Stores)
|
||||
AATags = AATags.merge(Store->getAAMetadata());
|
||||
if (auto CI = dyn_cast<ConstantInt>(NumBytes))
|
||||
AATags = AATags.extendTo(CI->getZExtValue());
|
||||
else
|
||||
@@ -1420,26 +1422,19 @@ bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(
|
||||
|
||||
// If the store is a memcpy instruction, we must check if it will write to
|
||||
// the load memory locations. So remove it from the ignored stores.
|
||||
if (IsMemCpy)
|
||||
IgnoredInsts.erase(TheStore);
|
||||
MemmoveVerifier Verifier(*LoadBasePtr, *StoreBasePtr, *DL);
|
||||
if (IsMemCpy && !Verifier.IsSameObject)
|
||||
IgnoredInsts.erase(TheStore);
|
||||
if (mayLoopAccessLocation(LoadBasePtr, ModRefInfo::Mod, CurLoop, BECount,
|
||||
StoreSizeSCEV, *AA, IgnoredInsts)) {
|
||||
if (!IsMemCpy) {
|
||||
ORE.emit([&]() {
|
||||
return OptimizationRemarkMissed(DEBUG_TYPE, "LoopMayAccessLoad",
|
||||
TheLoad)
|
||||
<< ore::NV("Inst", InstRemark) << " in "
|
||||
<< ore::NV("Function", TheStore->getFunction())
|
||||
<< " function will not be hoisted: "
|
||||
<< ore::NV("Reason", "The loop may access load location");
|
||||
});
|
||||
return Changed;
|
||||
}
|
||||
// At this point loop may access load only for memcpy in same underlying
|
||||
// object. If that's not the case bail out.
|
||||
if (!Verifier.IsSameObject)
|
||||
return Changed;
|
||||
ORE.emit([&]() {
|
||||
return OptimizationRemarkMissed(DEBUG_TYPE, "LoopMayAccessLoad", TheLoad)
|
||||
<< ore::NV("Inst", InstRemark) << " in "
|
||||
<< ore::NV("Function", TheStore->getFunction())
|
||||
<< " function will not be hoisted: "
|
||||
<< ore::NV("Reason", "The loop may access load location");
|
||||
});
|
||||
return Changed;
|
||||
}
|
||||
|
||||
bool UseMemMove = IsMemCpy ? Verifier.IsSameObject : LoopAccessStore;
|
||||
|
||||
@@ -2350,7 +2350,7 @@ static bool markAliveBlocks(Function &F,
|
||||
changeToUnreachable(II, false, DTU);
|
||||
Changed = true;
|
||||
} else if (II->doesNotThrow() && canSimplifyInvokeNoUnwind(&F)) {
|
||||
if (II->use_empty() && II->onlyReadsMemory()) {
|
||||
if (II->use_empty() && !II->mayHaveSideEffects()) {
|
||||
// jump to the normal destination branch.
|
||||
BasicBlock *NormalDestBB = II->getNormalDest();
|
||||
BasicBlock *UnwindDestBB = II->getUnwindDest();
|
||||
|
||||
Reference in New Issue
Block a user