Update llvm and clang to release_38 branch r261369.
This commit is contained in:
commit
ce479d84f4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/clang380-import/; revision=295859
@ -544,6 +544,11 @@ namespace llvm {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns true if any segment in the live range contains any of the
|
||||
// provided slot indexes. Slots which occur in holes between
|
||||
// segments will not cause the function to return true.
|
||||
bool isLiveAtIndexes(ArrayRef<SlotIndex> Slots) const;
|
||||
|
||||
bool operator<(const LiveRange& other) const {
|
||||
const SlotIndex &thisIndex = beginIndex();
|
||||
const SlotIndex &otherIndex = other.beginIndex();
|
||||
|
@ -1539,16 +1539,7 @@ class IRBuilder : public IRBuilderBase, public Inserter {
|
||||
}
|
||||
|
||||
CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args = None,
|
||||
ArrayRef<OperandBundleDef> OpBundles = None,
|
||||
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
|
||||
CallInst *CI = CallInst::Create(Callee, Args, OpBundles);
|
||||
if (isa<FPMathOperator>(CI))
|
||||
CI = cast<CallInst>(AddFPMathAttributes(CI, FPMathTag, FMF));
|
||||
return Insert(CI, Name);
|
||||
}
|
||||
|
||||
CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args,
|
||||
const Twine &Name, MDNode *FPMathTag = nullptr) {
|
||||
PointerType *PTy = cast<PointerType>(Callee->getType());
|
||||
FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
|
||||
return CreateCall(FTy, Callee, Args, Name, FPMathTag);
|
||||
@ -1563,6 +1554,15 @@ class IRBuilder : public IRBuilderBase, public Inserter {
|
||||
return Insert(CI, Name);
|
||||
}
|
||||
|
||||
CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args,
|
||||
ArrayRef<OperandBundleDef> OpBundles,
|
||||
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
|
||||
CallInst *CI = CallInst::Create(Callee, Args, OpBundles);
|
||||
if (isa<FPMathOperator>(CI))
|
||||
CI = cast<CallInst>(AddFPMathAttributes(CI, FPMathTag, FMF));
|
||||
return Insert(CI, Name);
|
||||
}
|
||||
|
||||
CallInst *CreateCall(Function *Callee, ArrayRef<Value *> Args,
|
||||
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
|
||||
return CreateCall(Callee->getFunctionType(), Callee, Args, Name, FPMathTag);
|
||||
|
@ -2512,6 +2512,14 @@ class PHINode : public Instruction {
|
||||
return block_begin() + getNumOperands();
|
||||
}
|
||||
|
||||
iterator_range<block_iterator> blocks() {
|
||||
return make_range(block_begin(), block_end());
|
||||
}
|
||||
|
||||
iterator_range<const_block_iterator> blocks() const {
|
||||
return make_range(block_begin(), block_end());
|
||||
}
|
||||
|
||||
op_range incoming_values() { return operands(); }
|
||||
|
||||
const_op_range incoming_values() const { return operands(); }
|
||||
|
@ -213,8 +213,11 @@ VirtRegAuxInfo::calculateSpillWeightAndHint(LiveInterval &li) {
|
||||
if (!Spillable)
|
||||
return;
|
||||
|
||||
// Mark li as unspillable if all live ranges are tiny.
|
||||
if (li.isZeroLength(LIS.getSlotIndexes())) {
|
||||
// Mark li as unspillable if all live ranges are tiny and the interval
|
||||
// is not live at any reg mask. If the interval is live at a reg mask
|
||||
// spilling may be required.
|
||||
if (li.isZeroLength(LIS.getSlotIndexes()) &&
|
||||
!li.isLiveAtIndexes(LIS.getRegMaskSlots())) {
|
||||
li.markNotSpillable();
|
||||
return;
|
||||
}
|
||||
|
@ -748,6 +748,40 @@ void LiveRange::flushSegmentSet() {
|
||||
verify();
|
||||
}
|
||||
|
||||
bool LiveRange::isLiveAtIndexes(ArrayRef<SlotIndex> Slots) const {
|
||||
ArrayRef<SlotIndex>::iterator SlotI = Slots.begin();
|
||||
ArrayRef<SlotIndex>::iterator SlotE = Slots.end();
|
||||
|
||||
// If there are no regmask slots, we have nothing to search.
|
||||
if (SlotI == SlotE)
|
||||
return false;
|
||||
|
||||
// Start our search at the first segment that ends after the first slot.
|
||||
const_iterator SegmentI = find(*SlotI);
|
||||
const_iterator SegmentE = end();
|
||||
|
||||
// If there are no segments that end after the first slot, we're done.
|
||||
if (SegmentI == SegmentE)
|
||||
return false;
|
||||
|
||||
// Look for each slot in the live range.
|
||||
for ( ; SlotI != SlotE; ++SlotI) {
|
||||
// Go to the next segment that ends after the current slot.
|
||||
// The slot may be within a hole in the range.
|
||||
SegmentI = advanceTo(SegmentI, *SlotI);
|
||||
if (SegmentI == SegmentE)
|
||||
return false;
|
||||
|
||||
// If this segment contains the slot, we're done.
|
||||
if (SegmentI->contains(*SlotI))
|
||||
return true;
|
||||
// Otherwise, look for the next slot.
|
||||
}
|
||||
|
||||
// We didn't find a segment containing any of the slots.
|
||||
return false;
|
||||
}
|
||||
|
||||
void LiveInterval::freeSubRange(SubRange *S) {
|
||||
S->~SubRange();
|
||||
// Memory was allocated with BumpPtr allocator and is not freed here.
|
||||
|
@ -1637,6 +1637,7 @@ struct FloatSignAsInt {
|
||||
MachinePointerInfo FloatPointerInfo;
|
||||
SDValue IntValue;
|
||||
APInt SignMask;
|
||||
uint8_t SignBit;
|
||||
};
|
||||
}
|
||||
|
||||
@ -1653,6 +1654,7 @@ void SelectionDAGLegalize::getSignAsIntValue(FloatSignAsInt &State,
|
||||
if (TLI.isTypeLegal(IVT)) {
|
||||
State.IntValue = DAG.getNode(ISD::BITCAST, DL, IVT, Value);
|
||||
State.SignMask = APInt::getSignBit(NumBits);
|
||||
State.SignBit = NumBits - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1689,6 +1691,7 @@ void SelectionDAGLegalize::getSignAsIntValue(FloatSignAsInt &State,
|
||||
IntPtr, State.IntPointerInfo, MVT::i8,
|
||||
false, false, false, 0);
|
||||
State.SignMask = APInt::getOneBitSet(LoadTy.getSizeInBits(), 7);
|
||||
State.SignBit = 7;
|
||||
}
|
||||
|
||||
/// Replace the integer value produced by getSignAsIntValue() with a new value
|
||||
@ -1731,15 +1734,38 @@ SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode *Node) const {
|
||||
return DAG.getSelect(DL, FloatVT, Cond, NegValue, AbsValue);
|
||||
}
|
||||
|
||||
// Transform values to integer, copy the sign bit and transform back.
|
||||
// Transform Mag value to integer, and clear the sign bit.
|
||||
FloatSignAsInt MagAsInt;
|
||||
getSignAsIntValue(MagAsInt, DL, Mag);
|
||||
assert(SignAsInt.SignMask == MagAsInt.SignMask);
|
||||
SDValue ClearSignMask = DAG.getConstant(~SignAsInt.SignMask, DL, IntVT);
|
||||
SDValue ClearedSign = DAG.getNode(ISD::AND, DL, IntVT, MagAsInt.IntValue,
|
||||
EVT MagVT = MagAsInt.IntValue.getValueType();
|
||||
SDValue ClearSignMask = DAG.getConstant(~MagAsInt.SignMask, DL, MagVT);
|
||||
SDValue ClearedSign = DAG.getNode(ISD::AND, DL, MagVT, MagAsInt.IntValue,
|
||||
ClearSignMask);
|
||||
SDValue CopiedSign = DAG.getNode(ISD::OR, DL, IntVT, ClearedSign, SignBit);
|
||||
|
||||
// Get the signbit at the right position for MagAsInt.
|
||||
int ShiftAmount = SignAsInt.SignBit - MagAsInt.SignBit;
|
||||
if (SignBit.getValueSizeInBits() > ClearedSign.getValueSizeInBits()) {
|
||||
if (ShiftAmount > 0) {
|
||||
SDValue ShiftCnst = DAG.getConstant(ShiftAmount, DL, IntVT);
|
||||
SignBit = DAG.getNode(ISD::SRL, DL, IntVT, SignBit, ShiftCnst);
|
||||
} else if (ShiftAmount < 0) {
|
||||
SDValue ShiftCnst = DAG.getConstant(-ShiftAmount, DL, IntVT);
|
||||
SignBit = DAG.getNode(ISD::SHL, DL, IntVT, SignBit, ShiftCnst);
|
||||
}
|
||||
SignBit = DAG.getNode(ISD::TRUNCATE, DL, MagVT, SignBit);
|
||||
} else if (SignBit.getValueSizeInBits() < ClearedSign.getValueSizeInBits()) {
|
||||
SignBit = DAG.getNode(ISD::ZERO_EXTEND, DL, MagVT, SignBit);
|
||||
if (ShiftAmount > 0) {
|
||||
SDValue ShiftCnst = DAG.getConstant(ShiftAmount, DL, MagVT);
|
||||
SignBit = DAG.getNode(ISD::SRL, DL, MagVT, SignBit, ShiftCnst);
|
||||
} else if (ShiftAmount < 0) {
|
||||
SDValue ShiftCnst = DAG.getConstant(-ShiftAmount, DL, MagVT);
|
||||
SignBit = DAG.getNode(ISD::SHL, DL, MagVT, SignBit, ShiftCnst);
|
||||
}
|
||||
}
|
||||
|
||||
// Store the part with the modified sign and convert back to float.
|
||||
SDValue CopiedSign = DAG.getNode(ISD::OR, DL, MagVT, ClearedSign, SignBit);
|
||||
return modifySignAsInt(MagAsInt, DL, CopiedSign);
|
||||
}
|
||||
|
||||
|
@ -257,12 +257,16 @@ static void calculateCXXStateNumbers(WinEHFuncInfo &FuncInfo,
|
||||
if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI))
|
||||
if (InnerCatchSwitch->getUnwindDest() == CatchSwitch->getUnwindDest())
|
||||
calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
|
||||
if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI))
|
||||
if (getCleanupRetUnwindDest(InnerCleanupPad) ==
|
||||
CatchSwitch->getUnwindDest())
|
||||
if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
|
||||
BasicBlock *UnwindDest = getCleanupRetUnwindDest(InnerCleanupPad);
|
||||
// If a nested cleanup pad reports a null unwind destination and the
|
||||
// enclosing catch pad doesn't it must be post-dominated by an
|
||||
// unreachable instruction.
|
||||
if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
|
||||
calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
|
||||
}
|
||||
}
|
||||
}
|
||||
int CatchHigh = FuncInfo.getLastStateNumber();
|
||||
addTryBlockMapEntry(FuncInfo, TryLow, TryHigh, CatchHigh, Handlers);
|
||||
DEBUG(dbgs() << "TryLow[" << BB->getName() << "]: " << TryLow << '\n');
|
||||
@ -360,11 +364,15 @@ static void calculateSEHStateNumbers(WinEHFuncInfo &FuncInfo,
|
||||
if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI))
|
||||
if (InnerCatchSwitch->getUnwindDest() == CatchSwitch->getUnwindDest())
|
||||
calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
|
||||
if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI))
|
||||
if (getCleanupRetUnwindDest(InnerCleanupPad) ==
|
||||
CatchSwitch->getUnwindDest())
|
||||
if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
|
||||
BasicBlock *UnwindDest = getCleanupRetUnwindDest(InnerCleanupPad);
|
||||
// If a nested cleanup pad reports a null unwind destination and the
|
||||
// enclosing catch pad doesn't it must be post-dominated by an
|
||||
// unreachable instruction.
|
||||
if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
|
||||
calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
|
||||
|
||||
|
@ -338,9 +338,9 @@ static Triple::ArchType parseArch(StringRef ArchName) {
|
||||
// FIXME: Do we need to support these?
|
||||
.Cases("i786", "i886", "i986", Triple::x86)
|
||||
.Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
|
||||
.Case("powerpc", Triple::ppc)
|
||||
.Cases("powerpc64", "ppu", Triple::ppc64)
|
||||
.Case("powerpc64le", Triple::ppc64le)
|
||||
.Cases("powerpc", "ppc32", Triple::ppc)
|
||||
.Cases("powerpc64", "ppu", "ppc64", Triple::ppc64)
|
||||
.Cases("powerpc64le", "ppc64le", Triple::ppc64le)
|
||||
.Case("xscale", Triple::arm)
|
||||
.Case("xscaleeb", Triple::armeb)
|
||||
.Case("aarch64", Triple::aarch64)
|
||||
@ -359,7 +359,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
|
||||
.Case("r600", Triple::r600)
|
||||
.Case("amdgcn", Triple::amdgcn)
|
||||
.Case("hexagon", Triple::hexagon)
|
||||
.Case("s390x", Triple::systemz)
|
||||
.Cases("s390x", "systemz", Triple::systemz)
|
||||
.Case("sparc", Triple::sparc)
|
||||
.Case("sparcel", Triple::sparcel)
|
||||
.Cases("sparcv9", "sparc64", Triple::sparcv9)
|
||||
|
@ -267,9 +267,9 @@ defm : int_cond_alias<"neg", 0b0110>;
|
||||
defm : int_cond_alias<"vc", 0b1111>;
|
||||
defm : int_cond_alias<"vs", 0b0111>;
|
||||
|
||||
defm : fp_cond_alias<"a", 0b0000>;
|
||||
defm : fp_cond_alias<"", 0b0000>; // same as a; gnu asm, not in manual
|
||||
defm : fp_cond_alias<"n", 0b1000>;
|
||||
defm : fp_cond_alias<"a", 0b1000>;
|
||||
defm : fp_cond_alias<"", 0b1000>; // same as a; gnu asm, not in manual
|
||||
defm : fp_cond_alias<"n", 0b0000>;
|
||||
defm : fp_cond_alias<"u", 0b0111>;
|
||||
defm : fp_cond_alias<"g", 0b0110>;
|
||||
defm : fp_cond_alias<"ug", 0b0101>;
|
||||
|
@ -69,19 +69,15 @@ class X86ELFObjectWriter : public MCELFObjectTargetWriter {
|
||||
class X86AsmBackend : public MCAsmBackend {
|
||||
const StringRef CPU;
|
||||
bool HasNopl;
|
||||
uint64_t MaxNopLength;
|
||||
const uint64_t MaxNopLength;
|
||||
public:
|
||||
X86AsmBackend(const Target &T, StringRef CPU) : MCAsmBackend(), CPU(CPU) {
|
||||
X86AsmBackend(const Target &T, StringRef CPU)
|
||||
: MCAsmBackend(), CPU(CPU), MaxNopLength(CPU == "slm" ? 7 : 15) {
|
||||
HasNopl = CPU != "generic" && CPU != "i386" && CPU != "i486" &&
|
||||
CPU != "i586" && CPU != "pentium" && CPU != "pentium-mmx" &&
|
||||
CPU != "i686" && CPU != "k6" && CPU != "k6-2" && CPU != "k6-3" &&
|
||||
CPU != "geode" && CPU != "winchip-c6" && CPU != "winchip2" &&
|
||||
CPU != "c3" && CPU != "c3-2";
|
||||
// Max length of true long nop instruction is 15 bytes.
|
||||
// Max length of long nop replacement instruction is 7 bytes.
|
||||
// Taking into account SilverMont architecture features max length of nops
|
||||
// is reduced for it to achieve better performance.
|
||||
MaxNopLength = (!HasNopl || CPU == "slm") ? 7 : 15;
|
||||
}
|
||||
|
||||
unsigned getNumFixupKinds() const override {
|
||||
@ -299,7 +295,7 @@ void X86AsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const {
|
||||
/// bytes.
|
||||
/// \return - true on success, false on failure
|
||||
bool X86AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
|
||||
static const uint8_t TrueNops[10][10] = {
|
||||
static const uint8_t Nops[10][10] = {
|
||||
// nop
|
||||
{0x90},
|
||||
// xchg %ax,%ax
|
||||
@ -322,31 +318,17 @@ bool X86AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
|
||||
{0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
};
|
||||
|
||||
// Alternative nop instructions for CPUs which don't support long nops.
|
||||
static const uint8_t AltNops[7][10] = {
|
||||
// nop
|
||||
{0x90},
|
||||
// xchg %ax,%ax
|
||||
{0x66, 0x90},
|
||||
// lea 0x0(%esi),%esi
|
||||
{0x8d, 0x76, 0x00},
|
||||
// lea 0x0(%esi),%esi
|
||||
{0x8d, 0x74, 0x26, 0x00},
|
||||
// nop + lea 0x0(%esi),%esi
|
||||
{0x90, 0x8d, 0x74, 0x26, 0x00},
|
||||
// lea 0x0(%esi),%esi
|
||||
{0x8d, 0xb6, 0x00, 0x00, 0x00, 0x00 },
|
||||
// lea 0x0(%esi),%esi
|
||||
{0x8d, 0xb4, 0x26, 0x00, 0x00, 0x00, 0x00},
|
||||
};
|
||||
// This CPU doesn't support long nops. If needed add more.
|
||||
// FIXME: Can we get this from the subtarget somehow?
|
||||
// FIXME: We could generated something better than plain 0x90.
|
||||
if (!HasNopl) {
|
||||
for (uint64_t i = 0; i < Count; ++i)
|
||||
OW->write8(0x90);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Select the right NOP table.
|
||||
// FIXME: Can we get if CPU supports long nops from the subtarget somehow?
|
||||
const uint8_t (*Nops)[10] = HasNopl ? TrueNops : AltNops;
|
||||
assert(HasNopl || MaxNopLength <= 7);
|
||||
|
||||
// Emit as many largest nops as needed, then emit a nop of the remaining
|
||||
// length.
|
||||
// 15 is the longest single nop instruction. Emit as many 15-byte nops as
|
||||
// needed, then emit a nop of the remaining length.
|
||||
do {
|
||||
const uint8_t ThisNopLength = (uint8_t) std::min(Count, MaxNopLength);
|
||||
const uint8_t Prefixes = ThisNopLength <= 10 ? 0 : ThisNopLength - 10;
|
||||
|
@ -192,10 +192,9 @@ static unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool isEAXLiveIn(MachineFunction &MF) {
|
||||
for (MachineRegisterInfo::livein_iterator II = MF.getRegInfo().livein_begin(),
|
||||
EE = MF.getRegInfo().livein_end(); II != EE; ++II) {
|
||||
unsigned Reg = II->first;
|
||||
static bool isEAXLiveIn(MachineBasicBlock &MBB) {
|
||||
for (MachineBasicBlock::RegisterMaskPair RegMask : MBB.liveins()) {
|
||||
unsigned Reg = RegMask.PhysReg;
|
||||
|
||||
if (Reg == X86::RAX || Reg == X86::EAX || Reg == X86::AX ||
|
||||
Reg == X86::AH || Reg == X86::AL)
|
||||
@ -261,7 +260,7 @@ void X86FrameLowering::emitSPUpdate(MachineBasicBlock &MBB,
|
||||
// load the offset into a register and do one sub/add
|
||||
unsigned Reg = 0;
|
||||
|
||||
if (isSub && !isEAXLiveIn(*MBB.getParent()))
|
||||
if (isSub && !isEAXLiveIn(MBB))
|
||||
Reg = (unsigned)(Is64Bit ? X86::RAX : X86::EAX);
|
||||
else
|
||||
Reg = findDeadCallerSavedReg(MBB, MBBI, TRI, Is64Bit);
|
||||
@ -1133,8 +1132,8 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
|
||||
if (IsWin64Prologue && !IsFunclet && TRI->needsStackRealignment(MF))
|
||||
AlignedNumBytes = RoundUpToAlignment(AlignedNumBytes, MaxAlign);
|
||||
if (AlignedNumBytes >= StackProbeSize && UseStackProbe) {
|
||||
// Check whether EAX is livein for this function.
|
||||
bool isEAXAlive = isEAXLiveIn(MF);
|
||||
// Check whether EAX is livein for this block.
|
||||
bool isEAXAlive = isEAXLiveIn(MBB);
|
||||
|
||||
if (isEAXAlive) {
|
||||
// Sanity check that EAX is not livein for this function.
|
||||
|
@ -5896,7 +5896,7 @@ multiclass avx512_sqrt_scalar<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
|
||||
|
||||
def : Pat<(_.EltVT (OpNode (load addr:$src))),
|
||||
(!cast<Instruction>(NAME#SUFF#Zm)
|
||||
(_.EltVT (IMPLICIT_DEF)), addr:$src)>, Requires<[OptForSize]>;
|
||||
(_.EltVT (IMPLICIT_DEF)), addr:$src)>, Requires<[HasAVX512, OptForSize]>;
|
||||
}
|
||||
|
||||
multiclass avx512_sqrt_scalar_all<bits<8> opc, string OpcodeStr> {
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/Transforms/Utils/Local.h"
|
||||
#include <algorithm>
|
||||
using namespace llvm;
|
||||
|
||||
@ -186,32 +187,8 @@ bool PruneEH::SimplifyFunction(Function *F) {
|
||||
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
|
||||
if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator()))
|
||||
if (II->doesNotThrow() && canSimplifyInvokeNoUnwind(F)) {
|
||||
SmallVector<Value*, 8> Args(II->arg_begin(), II->arg_end());
|
||||
SmallVector<OperandBundleDef, 1> OpBundles;
|
||||
II->getOperandBundlesAsDefs(OpBundles);
|
||||
|
||||
// Insert a call instruction before the invoke.
|
||||
CallInst *Call = CallInst::Create(II->getCalledValue(), Args, OpBundles,
|
||||
"", II);
|
||||
Call->takeName(II);
|
||||
Call->setCallingConv(II->getCallingConv());
|
||||
Call->setAttributes(II->getAttributes());
|
||||
Call->setDebugLoc(II->getDebugLoc());
|
||||
|
||||
// Anything that used the value produced by the invoke instruction
|
||||
// now uses the value produced by the call instruction. Note that we
|
||||
// do this even for void functions and calls with no uses so that the
|
||||
// callgraph edge is updated.
|
||||
II->replaceAllUsesWith(Call);
|
||||
BasicBlock *UnwindBlock = II->getUnwindDest();
|
||||
UnwindBlock->removePredecessor(II->getParent());
|
||||
|
||||
// Insert a branch to the normal destination right before the
|
||||
// invoke.
|
||||
BranchInst::Create(II->getNormalDest(), II);
|
||||
|
||||
// Finally, delete the invoke instruction!
|
||||
BB->getInstList().pop_back();
|
||||
removeUnwindEdge(&*BB);
|
||||
|
||||
// If the unwind block is now dead, nuke it.
|
||||
if (pred_empty(UnwindBlock))
|
||||
@ -251,18 +228,33 @@ void PruneEH::DeleteBasicBlock(BasicBlock *BB) {
|
||||
assert(pred_empty(BB) && "BB is not dead!");
|
||||
CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
|
||||
|
||||
Instruction *TokenInst = nullptr;
|
||||
|
||||
CallGraphNode *CGN = CG[BB->getParent()];
|
||||
for (BasicBlock::iterator I = BB->end(), E = BB->begin(); I != E; ) {
|
||||
--I;
|
||||
if (CallInst *CI = dyn_cast<CallInst>(I)) {
|
||||
if (!isa<IntrinsicInst>(I))
|
||||
CGN->removeCallEdgeFor(CI);
|
||||
} else if (InvokeInst *II = dyn_cast<InvokeInst>(I))
|
||||
CGN->removeCallEdgeFor(II);
|
||||
|
||||
if (I->getType()->isTokenTy()) {
|
||||
TokenInst = &*I;
|
||||
break;
|
||||
}
|
||||
|
||||
if (auto CS = CallSite (&*I)) {
|
||||
const Function *Callee = CS.getCalledFunction();
|
||||
if (!Callee || !Intrinsic::isLeaf(Callee->getIntrinsicID()))
|
||||
CGN->removeCallEdgeFor(CS);
|
||||
else if (!Callee->isIntrinsic())
|
||||
CGN->removeCallEdgeFor(CS);
|
||||
}
|
||||
|
||||
if (!I->use_empty())
|
||||
I->replaceAllUsesWith(UndefValue::get(I->getType()));
|
||||
}
|
||||
|
||||
if (TokenInst) {
|
||||
if (!isa<TerminatorInst>(TokenInst))
|
||||
changeToUnreachable(TokenInst->getNextNode(), /*UseLLVMTrap=*/false);
|
||||
} else {
|
||||
// Get the list of successors of this block.
|
||||
std::vector<BasicBlock *> Succs(succ_begin(BB), succ_end(BB));
|
||||
|
||||
@ -271,3 +263,4 @@ void PruneEH::DeleteBasicBlock(BasicBlock *BB) {
|
||||
|
||||
BB->eraseFromParent();
|
||||
}
|
||||
}
|
||||
|
@ -4799,6 +4799,17 @@ LSRInstance::LSRInstance(Loop *L, IVUsers &IU, ScalarEvolution &SE,
|
||||
DEBUG(dbgs() << "LSR skipping loop, too many IV Users in " << U << "\n");
|
||||
return;
|
||||
}
|
||||
// Bail out if we have a PHI on an EHPad that gets a value from a
|
||||
// CatchSwitchInst. Because the CatchSwitchInst cannot be split, there is
|
||||
// no good place to stick any instructions.
|
||||
if (auto *PN = dyn_cast<PHINode>(U.getUser())) {
|
||||
auto *FirstNonPHI = PN->getParent()->getFirstNonPHI();
|
||||
if (isa<FuncletPadInst>(FirstNonPHI) ||
|
||||
isa<CatchSwitchInst>(FirstNonPHI))
|
||||
for (BasicBlock *PredBB : PN->blocks())
|
||||
if (isa<CatchSwitchInst>(PredBB->getFirstNonPHI()))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -1409,14 +1409,15 @@ class LoopVectorizationLegality {
|
||||
/// different operations.
|
||||
class LoopVectorizationCostModel {
|
||||
public:
|
||||
LoopVectorizationCostModel(Loop *L, PredicatedScalarEvolution &PSE,
|
||||
LoopInfo *LI, LoopVectorizationLegality *Legal,
|
||||
LoopVectorizationCostModel(Loop *L, ScalarEvolution *SE, LoopInfo *LI,
|
||||
LoopVectorizationLegality *Legal,
|
||||
const TargetTransformInfo &TTI,
|
||||
const TargetLibraryInfo *TLI, DemandedBits *DB,
|
||||
AssumptionCache *AC, const Function *F,
|
||||
const LoopVectorizeHints *Hints)
|
||||
: TheLoop(L), PSE(PSE), LI(LI), Legal(Legal), TTI(TTI), TLI(TLI), DB(DB),
|
||||
AC(AC), TheFunction(F), Hints(Hints) {}
|
||||
const LoopVectorizeHints *Hints,
|
||||
SmallPtrSetImpl<const Value *> &ValuesToIgnore)
|
||||
: TheLoop(L), SE(SE), LI(LI), Legal(Legal), TTI(TTI), TLI(TLI), DB(DB),
|
||||
TheFunction(F), Hints(Hints), ValuesToIgnore(ValuesToIgnore) {}
|
||||
|
||||
/// Information about vectorization costs
|
||||
struct VectorizationFactor {
|
||||
@ -1464,9 +1465,6 @@ class LoopVectorizationCostModel {
|
||||
SmallVector<RegisterUsage, 8>
|
||||
calculateRegisterUsage(const SmallVector<unsigned, 8> &VFs);
|
||||
|
||||
/// Collect values we want to ignore in the cost model.
|
||||
void collectValuesToIgnore();
|
||||
|
||||
private:
|
||||
/// Returns the expected execution cost. The unit of the cost does
|
||||
/// not matter because we use the 'cost' units to compare different
|
||||
@ -1498,8 +1496,8 @@ class LoopVectorizationCostModel {
|
||||
|
||||
/// The loop that we evaluate.
|
||||
Loop *TheLoop;
|
||||
/// Predicated scalar evolution analysis.
|
||||
PredicatedScalarEvolution &PSE;
|
||||
/// Scev analysis.
|
||||
ScalarEvolution *SE;
|
||||
/// Loop Info analysis.
|
||||
LoopInfo *LI;
|
||||
/// Vectorization legality.
|
||||
@ -1508,17 +1506,13 @@ class LoopVectorizationCostModel {
|
||||
const TargetTransformInfo &TTI;
|
||||
/// Target Library Info.
|
||||
const TargetLibraryInfo *TLI;
|
||||
/// Demanded bits analysis.
|
||||
/// Demanded bits analysis
|
||||
DemandedBits *DB;
|
||||
/// Assumption cache.
|
||||
AssumptionCache *AC;
|
||||
const Function *TheFunction;
|
||||
/// Loop Vectorize Hint.
|
||||
// Loop Vectorize Hint.
|
||||
const LoopVectorizeHints *Hints;
|
||||
/// Values to ignore in the cost model.
|
||||
SmallPtrSet<const Value *, 16> ValuesToIgnore;
|
||||
/// Values to ignore in the cost model when VF > 1.
|
||||
SmallPtrSet<const Value *, 16> VecValuesToIgnore;
|
||||
// Values to ignore in the cost model.
|
||||
const SmallPtrSetImpl<const Value *> &ValuesToIgnore;
|
||||
};
|
||||
|
||||
/// \brief This holds vectorization requirements that must be verified late in
|
||||
@ -1763,10 +1757,19 @@ struct LoopVectorize : public FunctionPass {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Collect values we want to ignore in the cost model. This includes
|
||||
// type-promoting instructions we identified during reduction detection.
|
||||
SmallPtrSet<const Value *, 32> ValuesToIgnore;
|
||||
CodeMetrics::collectEphemeralValues(L, AC, ValuesToIgnore);
|
||||
for (auto &Reduction : *LVL.getReductionVars()) {
|
||||
RecurrenceDescriptor &RedDes = Reduction.second;
|
||||
SmallPtrSetImpl<Instruction *> &Casts = RedDes.getCastInsts();
|
||||
ValuesToIgnore.insert(Casts.begin(), Casts.end());
|
||||
}
|
||||
|
||||
// Use the cost model.
|
||||
LoopVectorizationCostModel CM(L, PSE, LI, &LVL, *TTI, TLI, DB, AC, F,
|
||||
&Hints);
|
||||
CM.collectValuesToIgnore();
|
||||
LoopVectorizationCostModel CM(L, PSE.getSE(), LI, &LVL, *TTI, TLI, DB, AC,
|
||||
F, &Hints, ValuesToIgnore);
|
||||
|
||||
// Check the function attributes to find out if this function should be
|
||||
// optimized for size.
|
||||
@ -4636,6 +4639,8 @@ void InterleavedAccessInfo::analyzeInterleaving(
|
||||
|
||||
// Holds all interleaved store groups temporarily.
|
||||
SmallSetVector<InterleaveGroup *, 4> StoreGroups;
|
||||
// Holds all interleaved load groups temporarily.
|
||||
SmallSetVector<InterleaveGroup *, 4> LoadGroups;
|
||||
|
||||
// Search the load-load/write-write pair B-A in bottom-up order and try to
|
||||
// insert B into the interleave group of A according to 3 rules:
|
||||
@ -4663,6 +4668,8 @@ void InterleavedAccessInfo::analyzeInterleaving(
|
||||
|
||||
if (A->mayWriteToMemory())
|
||||
StoreGroups.insert(Group);
|
||||
else
|
||||
LoadGroups.insert(Group);
|
||||
|
||||
for (auto II = std::next(I); II != E; ++II) {
|
||||
Instruction *B = II->first;
|
||||
@ -4710,6 +4717,12 @@ void InterleavedAccessInfo::analyzeInterleaving(
|
||||
for (InterleaveGroup *Group : StoreGroups)
|
||||
if (Group->getNumMembers() != Group->getFactor())
|
||||
releaseGroup(Group);
|
||||
|
||||
// Remove interleaved load groups that don't have the first and last member.
|
||||
// This guarantees that we won't do speculative out of bounds loads.
|
||||
for (InterleaveGroup *Group : LoadGroups)
|
||||
if (!Group->getMember(0) || !Group->getMember(Group->getFactor() - 1))
|
||||
releaseGroup(Group);
|
||||
}
|
||||
|
||||
LoopVectorizationCostModel::VectorizationFactor
|
||||
@ -4734,7 +4747,7 @@ LoopVectorizationCostModel::selectVectorizationFactor(bool OptForSize) {
|
||||
}
|
||||
|
||||
// Find the trip count.
|
||||
unsigned TC = PSE.getSE()->getSmallConstantTripCount(TheLoop);
|
||||
unsigned TC = SE->getSmallConstantTripCount(TheLoop);
|
||||
DEBUG(dbgs() << "LV: Found trip count: " << TC << '\n');
|
||||
|
||||
MinBWs = computeMinimumValueSizes(TheLoop->getBlocks(), *DB, &TTI);
|
||||
@ -4936,7 +4949,7 @@ unsigned LoopVectorizationCostModel::selectInterleaveCount(bool OptForSize,
|
||||
return 1;
|
||||
|
||||
// Do not interleave loops with a relatively small trip count.
|
||||
unsigned TC = PSE.getSE()->getSmallConstantTripCount(TheLoop);
|
||||
unsigned TC = SE->getSmallConstantTripCount(TheLoop);
|
||||
if (TC > 1 && TC < TinyTripCountInterleaveThreshold)
|
||||
return 1;
|
||||
|
||||
@ -5164,15 +5177,15 @@ LoopVectorizationCostModel::calculateRegisterUsage(
|
||||
// Ignore instructions that are never used within the loop.
|
||||
if (!Ends.count(I)) continue;
|
||||
|
||||
// Skip ignored values.
|
||||
if (ValuesToIgnore.count(I))
|
||||
continue;
|
||||
|
||||
// Remove all of the instructions that end at this location.
|
||||
InstrList &List = TransposeEnds[i];
|
||||
for (unsigned int j = 0, e = List.size(); j < e; ++j)
|
||||
OpenIntervals.erase(List[j]);
|
||||
|
||||
// Skip ignored values.
|
||||
if (ValuesToIgnore.count(I))
|
||||
continue;
|
||||
|
||||
// For each VF find the maximum usage of registers.
|
||||
for (unsigned j = 0, e = VFs.size(); j < e; ++j) {
|
||||
if (VFs[j] == 1) {
|
||||
@ -5182,12 +5195,8 @@ LoopVectorizationCostModel::calculateRegisterUsage(
|
||||
|
||||
// Count the number of live intervals.
|
||||
unsigned RegUsage = 0;
|
||||
for (auto Inst : OpenIntervals) {
|
||||
// Skip ignored values for VF > 1.
|
||||
if (VecValuesToIgnore.count(Inst))
|
||||
continue;
|
||||
for (auto Inst : OpenIntervals)
|
||||
RegUsage += GetRegUsage(Inst->getType(), VFs[j]);
|
||||
}
|
||||
MaxUsages[j] = std::max(MaxUsages[j], RegUsage);
|
||||
}
|
||||
|
||||
@ -5331,7 +5340,6 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, unsigned VF) {
|
||||
if (VF > 1 && MinBWs.count(I))
|
||||
RetTy = IntegerType::get(RetTy->getContext(), MinBWs[I]);
|
||||
Type *VectorTy = ToVectorTy(RetTy, VF);
|
||||
auto SE = PSE.getSE();
|
||||
|
||||
// TODO: We need to estimate the cost of intrinsic calls.
|
||||
switch (I->getOpcode()) {
|
||||
@ -5633,79 +5641,6 @@ bool LoopVectorizationCostModel::isConsecutiveLoadOrStore(Instruction *Inst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void LoopVectorizationCostModel::collectValuesToIgnore() {
|
||||
// Ignore ephemeral values.
|
||||
CodeMetrics::collectEphemeralValues(TheLoop, AC, ValuesToIgnore);
|
||||
|
||||
// Ignore type-promoting instructions we identified during reduction
|
||||
// detection.
|
||||
for (auto &Reduction : *Legal->getReductionVars()) {
|
||||
RecurrenceDescriptor &RedDes = Reduction.second;
|
||||
SmallPtrSetImpl<Instruction *> &Casts = RedDes.getCastInsts();
|
||||
VecValuesToIgnore.insert(Casts.begin(), Casts.end());
|
||||
}
|
||||
|
||||
// Ignore induction phis that are only used in either GetElementPtr or ICmp
|
||||
// instruction to exit loop. Induction variables usually have large types and
|
||||
// can have big impact when estimating register usage.
|
||||
// This is for when VF > 1.
|
||||
for (auto &Induction : *Legal->getInductionVars()) {
|
||||
auto *PN = Induction.first;
|
||||
auto *UpdateV = PN->getIncomingValueForBlock(TheLoop->getLoopLatch());
|
||||
|
||||
// Check that the PHI is only used by the induction increment (UpdateV) or
|
||||
// by GEPs. Then check that UpdateV is only used by a compare instruction or
|
||||
// the loop header PHI.
|
||||
// FIXME: Need precise def-use analysis to determine if this instruction
|
||||
// variable will be vectorized.
|
||||
if (std::all_of(PN->user_begin(), PN->user_end(),
|
||||
[&](const User *U) -> bool {
|
||||
return U == UpdateV || isa<GetElementPtrInst>(U);
|
||||
}) &&
|
||||
std::all_of(UpdateV->user_begin(), UpdateV->user_end(),
|
||||
[&](const User *U) -> bool {
|
||||
return U == PN || isa<ICmpInst>(U);
|
||||
})) {
|
||||
VecValuesToIgnore.insert(PN);
|
||||
VecValuesToIgnore.insert(UpdateV);
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore instructions that will not be vectorized.
|
||||
// This is for when VF > 1.
|
||||
for (auto bb = TheLoop->block_begin(), be = TheLoop->block_end(); bb != be;
|
||||
++bb) {
|
||||
for (auto &Inst : **bb) {
|
||||
switch (Inst.getOpcode()) {
|
||||
case Instruction::GetElementPtr: {
|
||||
// Ignore GEP if its last operand is an induction variable so that it is
|
||||
// a consecutive load/store and won't be vectorized as scatter/gather
|
||||
// pattern.
|
||||
|
||||
GetElementPtrInst *Gep = cast<GetElementPtrInst>(&Inst);
|
||||
unsigned NumOperands = Gep->getNumOperands();
|
||||
unsigned InductionOperand = getGEPInductionOperand(Gep);
|
||||
bool GepToIgnore = true;
|
||||
|
||||
// Check that all of the gep indices are uniform except for the
|
||||
// induction operand.
|
||||
for (unsigned i = 0; i != NumOperands; ++i) {
|
||||
if (i != InductionOperand &&
|
||||
!PSE.getSE()->isLoopInvariant(PSE.getSCEV(Gep->getOperand(i)),
|
||||
TheLoop)) {
|
||||
GepToIgnore = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (GepToIgnore)
|
||||
VecValuesToIgnore.insert(&Inst);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InnerLoopUnroller::scalarizeInstruction(Instruction *Instr,
|
||||
bool IfPredicateStore) {
|
||||
|
@ -4915,8 +4915,8 @@ class ARMTargetInfo : public TargetInfo {
|
||||
default: break;
|
||||
case 'l': // r0-r7
|
||||
case 'h': // r8-r15
|
||||
case 'w': // VFP Floating point register single precision
|
||||
case 'P': // VFP Floating point register double precision
|
||||
case 't': // VFP Floating point register single precision
|
||||
case 'w': // VFP Floating point register double precision
|
||||
Info.setAllowsRegister();
|
||||
return true;
|
||||
case 'I':
|
||||
|
@ -585,28 +585,15 @@ void CodeGenFunction::EmitOMPLastprivateClauseFinal(
|
||||
EmitBlock(ThenBB);
|
||||
}
|
||||
llvm::DenseMap<const Decl *, const Expr *> LoopCountersAndUpdates;
|
||||
const Expr *LastIterVal = nullptr;
|
||||
const Expr *IVExpr = nullptr;
|
||||
const Expr *IncExpr = nullptr;
|
||||
if (auto *LoopDirective = dyn_cast<OMPLoopDirective>(&D)) {
|
||||
if (isOpenMPWorksharingDirective(D.getDirectiveKind())) {
|
||||
LastIterVal = cast<VarDecl>(cast<DeclRefExpr>(
|
||||
LoopDirective->getUpperBoundVariable())
|
||||
->getDecl())
|
||||
->getAnyInitializer();
|
||||
IVExpr = LoopDirective->getIterationVariable();
|
||||
IncExpr = LoopDirective->getInc();
|
||||
auto IUpdate = LoopDirective->updates().begin();
|
||||
for (auto *E : LoopDirective->counters()) {
|
||||
auto *D = cast<DeclRefExpr>(E)->getDecl()->getCanonicalDecl();
|
||||
LoopCountersAndUpdates[D] = *IUpdate;
|
||||
++IUpdate;
|
||||
auto IC = LoopDirective->counters().begin();
|
||||
for (auto F : LoopDirective->finals()) {
|
||||
auto *D = cast<DeclRefExpr>(*IC)->getDecl()->getCanonicalDecl();
|
||||
LoopCountersAndUpdates[D] = F;
|
||||
++IC;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
|
||||
bool FirstLCV = true;
|
||||
for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
|
||||
auto IRef = C->varlist_begin();
|
||||
auto ISrcRef = C->source_exprs().begin();
|
||||
@ -619,16 +606,8 @@ void CodeGenFunction::EmitOMPLastprivateClauseFinal(
|
||||
// If lastprivate variable is a loop control variable for loop-based
|
||||
// directive, update its value before copyin back to original
|
||||
// variable.
|
||||
if (auto *UpExpr = LoopCountersAndUpdates.lookup(CanonicalVD)) {
|
||||
if (FirstLCV && LastIterVal) {
|
||||
EmitAnyExprToMem(LastIterVal, EmitLValue(IVExpr).getAddress(),
|
||||
IVExpr->getType().getQualifiers(),
|
||||
/*IsInitializer=*/false);
|
||||
EmitIgnoredExpr(IncExpr);
|
||||
FirstLCV = false;
|
||||
}
|
||||
if (auto *UpExpr = LoopCountersAndUpdates.lookup(CanonicalVD))
|
||||
EmitIgnoredExpr(UpExpr);
|
||||
}
|
||||
auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
|
||||
auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
|
||||
// Get the address of the original variable.
|
||||
@ -646,11 +625,9 @@ void CodeGenFunction::EmitOMPLastprivateClauseFinal(
|
||||
++IDestRef;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IsLastIterCond) {
|
||||
if (IsLastIterCond)
|
||||
EmitBlock(DoneBB, /*IsFinished=*/true);
|
||||
}
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitOMPReductionClauseInit(
|
||||
const OMPExecutableDirective &D,
|
||||
@ -919,10 +896,6 @@ void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D,
|
||||
// The end (updates/cleanups).
|
||||
EmitBlock(Continue.getBlock());
|
||||
BreakContinueStack.pop_back();
|
||||
// TODO: Update lastprivates if the SeparateIter flag is true.
|
||||
// This will be implemented in a follow-up OMPLastprivateClause patch, but
|
||||
// result should be still correct without it, as we do not make these
|
||||
// variables private yet.
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitOMPInnerLoop(
|
||||
|
@ -4868,9 +4868,6 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
};
|
||||
|
||||
class WindowsARMTargetCodeGenInfo : public ARMTargetCodeGenInfo {
|
||||
void addStackProbeSizeTargetAttribute(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &CGM) const;
|
||||
|
||||
public:
|
||||
WindowsARMTargetCodeGenInfo(CodeGenTypes &CGT, ARMABIInfo::ABIKind K)
|
||||
: ARMTargetCodeGenInfo(CGT, K) {}
|
||||
@ -4879,18 +4876,6 @@ class WindowsARMTargetCodeGenInfo : public ARMTargetCodeGenInfo {
|
||||
CodeGen::CodeGenModule &CGM) const override;
|
||||
};
|
||||
|
||||
void WindowsARMTargetCodeGenInfo::addStackProbeSizeTargetAttribute(
|
||||
const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const {
|
||||
if (!isa<FunctionDecl>(D))
|
||||
return;
|
||||
if (CGM.getCodeGenOpts().StackProbeSize == 4096)
|
||||
return;
|
||||
|
||||
llvm::Function *F = cast<llvm::Function>(GV);
|
||||
F->addFnAttr("stack-probe-size",
|
||||
llvm::utostr(CGM.getCodeGenOpts().StackProbeSize));
|
||||
}
|
||||
|
||||
void WindowsARMTargetCodeGenInfo::setTargetAttributes(
|
||||
const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const {
|
||||
ARMTargetCodeGenInfo::setTargetAttributes(D, GV, CGM);
|
||||
|
@ -3108,6 +3108,22 @@ void FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
|
||||
}
|
||||
}
|
||||
|
||||
void FreeBSD::AddCXXStdlibLibArgs(const ArgList &Args,
|
||||
ArgStringList &CmdArgs) const {
|
||||
CXXStdlibType Type = GetCXXStdlibType(Args);
|
||||
bool Profiling = Args.hasArg(options::OPT_pg);
|
||||
|
||||
switch (Type) {
|
||||
case ToolChain::CST_Libcxx:
|
||||
CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++");
|
||||
break;
|
||||
|
||||
case ToolChain::CST_Libstdcxx:
|
||||
CmdArgs.push_back(Profiling ? "-lstdc++_p" : "-lstdc++");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Tool *FreeBSD::buildAssembler() const {
|
||||
return new tools::freebsd::Assembler(*this);
|
||||
}
|
||||
|
@ -722,6 +722,8 @@ class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF {
|
||||
void AddClangCXXStdlibIncludeArgs(
|
||||
const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args) const override;
|
||||
void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
|
||||
llvm::opt::ArgStringList &CmdArgs) const override;
|
||||
|
||||
bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override;
|
||||
bool isPIEDefault() const override;
|
||||
|
@ -182,7 +182,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
|
||||
return true;
|
||||
|
||||
unsigned NewLineColumn = getNewLineColumn(State);
|
||||
if (Current.isMemberAccess() &&
|
||||
if (Current.isMemberAccess() && Style.ColumnLimit != 0 &&
|
||||
State.Column + getLengthToNextOperator(Current) > Style.ColumnLimit &&
|
||||
(State.Column > NewLineColumn ||
|
||||
Current.NestingLevel < State.StartOfLineLevel))
|
||||
|
@ -634,7 +634,8 @@ DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) {
|
||||
if (auto *CTD = CTSD->getSpecializedTemplate())
|
||||
RD = CTD->getTemplatedDecl();
|
||||
if (IsConstant &&
|
||||
!(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasMutableFields())) {
|
||||
!(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() &&
|
||||
RD->hasMutableFields())) {
|
||||
// Variables with const-qualified type having no mutable member may be
|
||||
// listed in a firstprivate clause, even if they are static data members.
|
||||
DSAVarData DVarTemp = hasDSA(D, MatchesAnyClause(OMPC_firstprivate),
|
||||
@ -3204,7 +3205,7 @@ class TransformToNewDefs : public TreeTransform<TransformToNewDefs> {
|
||||
NewVD->setInitStyle(VD->getInitStyle());
|
||||
NewVD->setExceptionVariable(VD->isExceptionVariable());
|
||||
NewVD->setNRVOVariable(VD->isNRVOVariable());
|
||||
NewVD->setCXXForRangeDecl(VD->isInExternCXXContext());
|
||||
NewVD->setCXXForRangeDecl(VD->isCXXForRangeDecl());
|
||||
NewVD->setConstexpr(VD->isConstexpr());
|
||||
NewVD->setInitCapture(VD->isInitCapture());
|
||||
NewVD->setPreviousDeclInSameBlockScope(
|
||||
@ -3249,14 +3250,20 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S,
|
||||
Expr *Lower = Transform.TransformExpr(LBExpr).get();
|
||||
if (!Upper || !Lower)
|
||||
return nullptr;
|
||||
Upper = SemaRef.PerformImplicitConversion(Upper, UBExpr->getType(),
|
||||
if (!SemaRef.Context.hasSameType(Upper->getType(), UBExpr->getType())) {
|
||||
Upper = SemaRef
|
||||
.PerformImplicitConversion(Upper, UBExpr->getType(),
|
||||
Sema::AA_Converting,
|
||||
/*AllowExplicit=*/true)
|
||||
.get();
|
||||
Lower = SemaRef.PerformImplicitConversion(Lower, LBExpr->getType(),
|
||||
}
|
||||
if (!SemaRef.Context.hasSameType(Lower->getType(), LBExpr->getType())) {
|
||||
Lower = SemaRef
|
||||
.PerformImplicitConversion(Lower, LBExpr->getType(),
|
||||
Sema::AA_Converting,
|
||||
/*AllowExplicit=*/true)
|
||||
.get();
|
||||
}
|
||||
if (!Upper || !Lower)
|
||||
return nullptr;
|
||||
|
||||
@ -3283,14 +3290,18 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S,
|
||||
return nullptr;
|
||||
|
||||
// Upper - Lower [- 1] + Step
|
||||
auto NewStep = Transform.TransformExpr(Step->IgnoreImplicit());
|
||||
auto *StepNoImp = Step->IgnoreImplicit();
|
||||
auto NewStep = Transform.TransformExpr(StepNoImp);
|
||||
if (NewStep.isInvalid())
|
||||
return nullptr;
|
||||
if (!SemaRef.Context.hasSameType(NewStep.get()->getType(),
|
||||
StepNoImp->getType())) {
|
||||
NewStep = SemaRef.PerformImplicitConversion(
|
||||
NewStep.get(), Step->IgnoreImplicit()->getType(), Sema::AA_Converting,
|
||||
NewStep.get(), StepNoImp->getType(), Sema::AA_Converting,
|
||||
/*AllowExplicit=*/true);
|
||||
if (NewStep.isInvalid())
|
||||
return nullptr;
|
||||
}
|
||||
Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
|
||||
if (!Diff.isUsable())
|
||||
return nullptr;
|
||||
@ -3301,14 +3312,17 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S,
|
||||
return nullptr;
|
||||
|
||||
// (Upper - Lower [- 1] + Step) / Step
|
||||
NewStep = Transform.TransformExpr(Step->IgnoreImplicit());
|
||||
NewStep = Transform.TransformExpr(StepNoImp);
|
||||
if (NewStep.isInvalid())
|
||||
return nullptr;
|
||||
if (!SemaRef.Context.hasSameType(NewStep.get()->getType(),
|
||||
StepNoImp->getType())) {
|
||||
NewStep = SemaRef.PerformImplicitConversion(
|
||||
NewStep.get(), Step->IgnoreImplicit()->getType(), Sema::AA_Converting,
|
||||
NewStep.get(), StepNoImp->getType(), Sema::AA_Converting,
|
||||
/*AllowExplicit=*/true);
|
||||
if (NewStep.isInvalid())
|
||||
return nullptr;
|
||||
}
|
||||
Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
|
||||
if (!Diff.isUsable())
|
||||
return nullptr;
|
||||
@ -3324,11 +3338,13 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S,
|
||||
bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
|
||||
: Type->hasSignedIntegerRepresentation();
|
||||
Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
|
||||
if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
|
||||
Diff = SemaRef.PerformImplicitConversion(
|
||||
Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
|
||||
if (!Diff.isUsable())
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
if (LimitedType) {
|
||||
unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
|
||||
if (NewSize != C.getTypeSize(Type)) {
|
||||
@ -3340,12 +3356,14 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S,
|
||||
QualType NewType = C.getIntTypeForBitwidth(
|
||||
NewSize, Type->hasSignedIntegerRepresentation() ||
|
||||
C.getTypeSize(Type) < NewSize);
|
||||
if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
|
||||
Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
|
||||
Sema::AA_Converting, true);
|
||||
if (!Diff.isUsable())
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Diff.get();
|
||||
}
|
||||
@ -3360,12 +3378,16 @@ Expr *OpenMPIterationSpaceChecker::BuildPreCond(Scope *S, Expr *Cond) const {
|
||||
auto NewUB = Transform.TransformExpr(UB);
|
||||
if (NewLB.isInvalid() || NewUB.isInvalid())
|
||||
return Cond;
|
||||
if (!SemaRef.Context.hasSameType(NewLB.get()->getType(), LB->getType())) {
|
||||
NewLB = SemaRef.PerformImplicitConversion(NewLB.get(), LB->getType(),
|
||||
Sema::AA_Converting,
|
||||
/*AllowExplicit=*/true);
|
||||
}
|
||||
if (!SemaRef.Context.hasSameType(NewUB.get()->getType(), UB->getType())) {
|
||||
NewUB = SemaRef.PerformImplicitConversion(NewUB.get(), UB->getType(),
|
||||
Sema::AA_Converting,
|
||||
/*AllowExplicit=*/true);
|
||||
}
|
||||
if (NewLB.isInvalid() || NewUB.isInvalid())
|
||||
return Cond;
|
||||
auto CondExpr = SemaRef.BuildBinOp(
|
||||
@ -3373,6 +3395,8 @@ Expr *OpenMPIterationSpaceChecker::BuildPreCond(Scope *S, Expr *Cond) const {
|
||||
: (TestIsStrictOp ? BO_GT : BO_GE),
|
||||
NewLB.get(), NewUB.get());
|
||||
if (CondExpr.isUsable()) {
|
||||
if (!SemaRef.Context.hasSameType(CondExpr.get()->getType(),
|
||||
SemaRef.Context.BoolTy))
|
||||
CondExpr = SemaRef.PerformImplicitConversion(
|
||||
CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
|
||||
/*AllowExplicit=*/true);
|
||||
@ -3602,20 +3626,26 @@ static ExprResult BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc,
|
||||
ExprResult VarRef, ExprResult Start) {
|
||||
TransformToNewDefs Transform(SemaRef);
|
||||
// Build 'VarRef = Start.
|
||||
auto NewStart = Transform.TransformExpr(Start.get()->IgnoreImplicit());
|
||||
auto *StartNoImp = Start.get()->IgnoreImplicit();
|
||||
auto NewStart = Transform.TransformExpr(StartNoImp);
|
||||
if (NewStart.isInvalid())
|
||||
return ExprError();
|
||||
if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
|
||||
StartNoImp->getType())) {
|
||||
NewStart = SemaRef.PerformImplicitConversion(
|
||||
NewStart.get(), Start.get()->IgnoreImplicit()->getType(),
|
||||
Sema::AA_Converting,
|
||||
NewStart.get(), StartNoImp->getType(), Sema::AA_Converting,
|
||||
/*AllowExplicit=*/true);
|
||||
if (NewStart.isInvalid())
|
||||
return ExprError();
|
||||
}
|
||||
if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
|
||||
VarRef.get()->getType())) {
|
||||
NewStart = SemaRef.PerformImplicitConversion(
|
||||
NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
|
||||
/*AllowExplicit=*/true);
|
||||
if (!NewStart.isUsable())
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
auto Init =
|
||||
SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
|
||||
@ -3633,31 +3663,37 @@ static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S,
|
||||
!Step.isUsable())
|
||||
return ExprError();
|
||||
|
||||
auto *StepNoImp = Step.get()->IgnoreImplicit();
|
||||
TransformToNewDefs Transform(SemaRef);
|
||||
auto NewStep = Transform.TransformExpr(Step.get()->IgnoreImplicit());
|
||||
auto NewStep = Transform.TransformExpr(StepNoImp);
|
||||
if (NewStep.isInvalid())
|
||||
return ExprError();
|
||||
if (!SemaRef.Context.hasSameType(NewStep.get()->getType(),
|
||||
StepNoImp->getType())) {
|
||||
NewStep = SemaRef.PerformImplicitConversion(
|
||||
NewStep.get(), Step.get()->IgnoreImplicit()->getType(),
|
||||
Sema::AA_Converting,
|
||||
NewStep.get(), StepNoImp->getType(), Sema::AA_Converting,
|
||||
/*AllowExplicit=*/true);
|
||||
if (NewStep.isInvalid())
|
||||
return ExprError();
|
||||
}
|
||||
ExprResult Update =
|
||||
SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
|
||||
if (!Update.isUsable())
|
||||
return ExprError();
|
||||
|
||||
// Build 'VarRef = Start + Iter * Step'.
|
||||
auto NewStart = Transform.TransformExpr(Start.get()->IgnoreImplicit());
|
||||
auto *StartNoImp = Start.get()->IgnoreImplicit();
|
||||
auto NewStart = Transform.TransformExpr(StartNoImp);
|
||||
if (NewStart.isInvalid())
|
||||
return ExprError();
|
||||
if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
|
||||
StartNoImp->getType())) {
|
||||
NewStart = SemaRef.PerformImplicitConversion(
|
||||
NewStart.get(), Start.get()->IgnoreImplicit()->getType(),
|
||||
Sema::AA_Converting,
|
||||
NewStart.get(), StartNoImp->getType(), Sema::AA_Converting,
|
||||
/*AllowExplicit=*/true);
|
||||
if (NewStart.isInvalid())
|
||||
return ExprError();
|
||||
}
|
||||
Update = SemaRef.BuildBinOp(S, Loc, (Subtract ? BO_Sub : BO_Add),
|
||||
NewStart.get(), Update.get());
|
||||
if (!Update.isUsable())
|
||||
|
@ -7,4 +7,4 @@
|
||||
|
||||
#define CLANG_VENDOR "FreeBSD "
|
||||
|
||||
#define SVN_REVISION "260756"
|
||||
#define SVN_REVISION "261369"
|
||||
|
Loading…
Reference in New Issue
Block a user