Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to

6.0.0 (branches/release_60 r323948).

MFC after:	3 months
X-MFC-With:	r327952
PR:		224669
This commit is contained in:
Dimitry Andric 2018-02-01 21:41:15 +00:00
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=328753
27 changed files with 277 additions and 108 deletions

View File

@ -79,25 +79,27 @@ struct Mapping {
#define TSAN_MID_APP_RANGE 1
#elif defined(__mips64)
/*
C/C++ on linux/mips64
0100 0000 00 - 0200 0000 00: main binary
0200 0000 00 - 1400 0000 00: -
1400 0000 00 - 2400 0000 00: shadow
2400 0000 00 - 3000 0000 00: -
3000 0000 00 - 4000 0000 00: metainfo (memory blocks and sync objects)
4000 0000 00 - 6000 0000 00: -
6000 0000 00 - 6200 0000 00: traces
6200 0000 00 - fe00 0000 00: -
fe00 0000 00 - ff00 0000 00: heap
ff00 0000 00 - ff80 0000 00: -
ff80 0000 00 - ffff ffff ff: modules and main thread stack
C/C++ on linux/mips64 (40-bit VMA)
0000 0000 00 - 0100 0000 00: - (4 GB)
0100 0000 00 - 0200 0000 00: main binary (4 GB)
0200 0000 00 - 2000 0000 00: - (120 GB)
2000 0000 00 - 4000 0000 00: shadow (128 GB)
4000 0000 00 - 5000 0000 00: metainfo (memory blocks and sync objects) (64 GB)
5000 0000 00 - aa00 0000 00: - (360 GB)
aa00 0000 00 - ab00 0000 00: main binary (PIE) (4 GB)
ab00 0000 00 - b000 0000 00: - (20 GB)
b000 0000 00 - b200 0000 00: traces (8 GB)
b200 0000 00 - fe00 0000 00: - (304 GB)
fe00 0000 00 - ff00 0000 00: heap (4 GB)
ff00 0000 00 - ff80 0000 00: - (2 GB)
ff80 0000 00 - ffff ffff ff: modules and main thread stack (<2 GB)
*/
struct Mapping {
static const uptr kMetaShadowBeg = 0x4000000000ull;
static const uptr kMetaShadowEnd = 0x5000000000ull;
static const uptr kTraceMemBeg = 0xb000000000ull;
static const uptr kTraceMemEnd = 0xb200000000ull;
static const uptr kShadowBeg = 0x2400000000ull;
static const uptr kShadowBeg = 0x2000000000ull;
static const uptr kShadowEnd = 0x4000000000ull;
static const uptr kHeapMemBeg = 0xfe00000000ull;
static const uptr kHeapMemEnd = 0xff00000000ull;

View File

@ -508,7 +508,8 @@ class Value;
/// -> LHS = %a, RHS = i32 4, *CastOp = Instruction::SExt
///
SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS,
Instruction::CastOps *CastOp = nullptr);
Instruction::CastOps *CastOp = nullptr,
unsigned Depth = 0);
inline SelectPatternResult
matchSelectPattern(const Value *V, const Value *&LHS, const Value *&RHS,
Instruction::CastOps *CastOp = nullptr) {

View File

@ -4165,17 +4165,18 @@ static SelectPatternResult matchClamp(CmpInst::Predicate Pred,
/// a < c ? min(a,b) : min(b,c) ==> min(min(a,b),min(b,c))
static SelectPatternResult matchMinMaxOfMinMax(CmpInst::Predicate Pred,
Value *CmpLHS, Value *CmpRHS,
Value *TrueVal, Value *FalseVal) {
Value *TVal, Value *FVal,
unsigned Depth) {
// TODO: Allow FP min/max with nnan/nsz.
assert(CmpInst::isIntPredicate(Pred) && "Expected integer comparison");
Value *A, *B;
SelectPatternResult L = matchSelectPattern(TrueVal, A, B);
SelectPatternResult L = matchSelectPattern(TVal, A, B, nullptr, Depth + 1);
if (!SelectPatternResult::isMinOrMax(L.Flavor))
return {SPF_UNKNOWN, SPNB_NA, false};
Value *C, *D;
SelectPatternResult R = matchSelectPattern(FalseVal, C, D);
SelectPatternResult R = matchSelectPattern(FVal, C, D, nullptr, Depth + 1);
if (L.Flavor != R.Flavor)
return {SPF_UNKNOWN, SPNB_NA, false};
@ -4240,7 +4241,8 @@ static SelectPatternResult matchMinMaxOfMinMax(CmpInst::Predicate Pred,
static SelectPatternResult matchMinMax(CmpInst::Predicate Pred,
Value *CmpLHS, Value *CmpRHS,
Value *TrueVal, Value *FalseVal,
Value *&LHS, Value *&RHS) {
Value *&LHS, Value *&RHS,
unsigned Depth) {
// Assume success. If there's no match, callers should not use these anyway.
LHS = TrueVal;
RHS = FalseVal;
@ -4249,7 +4251,7 @@ static SelectPatternResult matchMinMax(CmpInst::Predicate Pred,
if (SPR.Flavor != SelectPatternFlavor::SPF_UNKNOWN)
return SPR;
SPR = matchMinMaxOfMinMax(Pred, CmpLHS, CmpRHS, TrueVal, FalseVal);
SPR = matchMinMaxOfMinMax(Pred, CmpLHS, CmpRHS, TrueVal, FalseVal, Depth);
if (SPR.Flavor != SelectPatternFlavor::SPF_UNKNOWN)
return SPR;
@ -4313,7 +4315,8 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred,
FastMathFlags FMF,
Value *CmpLHS, Value *CmpRHS,
Value *TrueVal, Value *FalseVal,
Value *&LHS, Value *&RHS) {
Value *&LHS, Value *&RHS,
unsigned Depth) {
LHS = CmpLHS;
RHS = CmpRHS;
@ -4429,7 +4432,7 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred,
}
if (CmpInst::isIntPredicate(Pred))
return matchMinMax(Pred, CmpLHS, CmpRHS, TrueVal, FalseVal, LHS, RHS);
return matchMinMax(Pred, CmpLHS, CmpRHS, TrueVal, FalseVal, LHS, RHS, Depth);
// According to (IEEE 754-2008 5.3.1), minNum(0.0, -0.0) and similar
// may return either -0.0 or 0.0, so fcmp/select pair has stricter
@ -4550,7 +4553,11 @@ static Value *lookThroughCast(CmpInst *CmpI, Value *V1, Value *V2,
}
SelectPatternResult llvm::matchSelectPattern(Value *V, Value *&LHS, Value *&RHS,
Instruction::CastOps *CastOp) {
Instruction::CastOps *CastOp,
unsigned Depth) {
if (Depth >= MaxDepth)
return {SPF_UNKNOWN, SPNB_NA, false};
SelectInst *SI = dyn_cast<SelectInst>(V);
if (!SI) return {SPF_UNKNOWN, SPNB_NA, false};
@ -4579,7 +4586,7 @@ SelectPatternResult llvm::matchSelectPattern(Value *V, Value *&LHS, Value *&RHS,
FMF.setNoSignedZeros();
return ::matchSelectPattern(Pred, FMF, CmpLHS, CmpRHS,
cast<CastInst>(TrueVal)->getOperand(0), C,
LHS, RHS);
LHS, RHS, Depth);
}
if (Value *C = lookThroughCast(CmpI, FalseVal, TrueVal, CastOp)) {
// If this is a potential fmin/fmax with a cast to integer, then ignore
@ -4588,11 +4595,11 @@ SelectPatternResult llvm::matchSelectPattern(Value *V, Value *&LHS, Value *&RHS,
FMF.setNoSignedZeros();
return ::matchSelectPattern(Pred, FMF, CmpLHS, CmpRHS,
C, cast<CastInst>(FalseVal)->getOperand(0),
LHS, RHS);
LHS, RHS, Depth);
}
}
return ::matchSelectPattern(Pred, FMF, CmpLHS, CmpRHS, TrueVal, FalseVal,
LHS, RHS);
LHS, RHS, Depth);
}
/// Return true if "icmp Pred LHS RHS" is always true.

View File

@ -812,6 +812,10 @@ bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) {
auto TII = MF->getTarget().getIntrinsicInfo();
const Function *F = CI.getCalledFunction();
// FIXME: support Windows dllimport function calls.
if (F && F->hasDLLImportStorageClass())
return false;
if (CI.isInlineAsm())
return translateInlineAsm(CI, MIRBuilder);

View File

@ -661,7 +661,24 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
}
case TargetOpcode::G_FCONSTANT: {
unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
MIRBuilder.buildFConstant(DstExt, *MI.getOperand(1).getFPImm());
const ConstantFP *CFP = MI.getOperand(1).getFPImm();
APFloat Val = CFP->getValueAPF();
LLVMContext &Ctx = MIRBuilder.getMF().getFunction().getContext();
auto LLT2Sem = [](LLT Ty) {
switch (Ty.getSizeInBits()) {
case 32:
return &APFloat::IEEEsingle();
break;
case 64:
return &APFloat::IEEEdouble();
break;
default:
llvm_unreachable("Unhandled fp widen type");
}
};
bool LosesInfo;
Val.convert(*LLT2Sem(WideTy), APFloat::rmTowardZero, &LosesInfo);
MIRBuilder.buildFConstant(DstExt, *ConstantFP::get(Ctx, Val));
MIRBuilder.buildFPTrunc(MI.getOperand(0).getReg(), DstExt);
MI.eraseFromParent();
return Legalized;

View File

@ -193,9 +193,10 @@ namespace {
void spillVirtReg(MachineBasicBlock::iterator MI, unsigned VirtReg);
void usePhysReg(MachineOperand &MO);
void definePhysReg(MachineInstr &MI, MCPhysReg PhysReg, RegState NewState);
void definePhysReg(MachineBasicBlock::iterator MI, MCPhysReg PhysReg,
RegState NewState);
unsigned calcSpillCost(MCPhysReg PhysReg) const;
void assignVirtToPhysReg(LiveReg&, MCPhysReg PhysReg);
void assignVirtToPhysReg(LiveReg &, MCPhysReg PhysReg);
LiveRegMap::iterator findLiveVirtReg(unsigned VirtReg) {
return LiveVirtRegs.find(TargetRegisterInfo::virtReg2Index(VirtReg));
@ -434,8 +435,8 @@ void RegAllocFast::usePhysReg(MachineOperand &MO) {
/// Mark PhysReg as reserved or free after spilling any virtregs. This is very
/// similar to defineVirtReg except the physreg is reserved instead of
/// allocated.
void RegAllocFast::definePhysReg(MachineInstr &MI, MCPhysReg PhysReg,
RegState NewState) {
void RegAllocFast::definePhysReg(MachineBasicBlock::iterator MI,
MCPhysReg PhysReg, RegState NewState) {
markRegUsedInInstr(PhysReg);
switch (unsigned VirtReg = PhysRegState[PhysReg]) {
case regDisabled:
@ -857,7 +858,7 @@ void RegAllocFast::allocateBasicBlock(MachineBasicBlock &MBB) {
// Add live-in registers as live.
for (const MachineBasicBlock::RegisterMaskPair LI : MBB.liveins())
if (MRI->isAllocatable(LI.PhysReg))
definePhysReg(*MII, LI.PhysReg, regReserved);
definePhysReg(MII, LI.PhysReg, regReserved);
VirtDead.clear();
Coalesced.clear();

View File

@ -1380,8 +1380,10 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
FastISelFailed = false;
// Initialize the Fast-ISel state, if needed.
FastISel *FastIS = nullptr;
if (TM.Options.EnableFastISel)
if (TM.Options.EnableFastISel) {
DEBUG(dbgs() << "Enabling fast-isel\n");
FastIS = TLI->createFastISel(*FuncInfo, LibInfo);
}
setupSwiftErrorVals(Fn, TLI, FuncInfo);

View File

@ -717,6 +717,8 @@ bool TargetPassConfig::addCoreISelPasses() {
if (EnableGlobalISel == cl::BOU_TRUE ||
(EnableGlobalISel == cl::BOU_UNSET && isGlobalISelEnabled() &&
EnableFastISelOption != cl::BOU_TRUE)) {
TM->setFastISel(false);
if (addIRTranslator())
return true;

View File

@ -476,26 +476,27 @@ unsigned AArch64FastISel::materializeGV(const GlobalValue *GV) {
// ADRP + LDRX
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADRP),
ADRPReg)
.addGlobalAddress(GV, 0, AArch64II::MO_GOT | AArch64II::MO_PAGE);
.addGlobalAddress(GV, 0, AArch64II::MO_PAGE | OpFlags);
ResultReg = createResultReg(&AArch64::GPR64RegClass);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::LDRXui),
ResultReg)
.addReg(ADRPReg)
.addGlobalAddress(GV, 0, AArch64II::MO_GOT | AArch64II::MO_PAGEOFF |
AArch64II::MO_NC);
.addReg(ADRPReg)
.addGlobalAddress(GV, 0,
AArch64II::MO_PAGEOFF | AArch64II::MO_NC | OpFlags);
} else {
// ADRP + ADDX
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADRP),
ADRPReg)
.addGlobalAddress(GV, 0, AArch64II::MO_PAGE);
.addGlobalAddress(GV, 0, AArch64II::MO_PAGE | OpFlags);
ResultReg = createResultReg(&AArch64::GPR64spRegClass);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADDXri),
ResultReg)
.addReg(ADRPReg)
.addGlobalAddress(GV, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC)
.addImm(0);
.addReg(ADRPReg)
.addGlobalAddress(GV, 0,
AArch64II::MO_PAGEOFF | AArch64II::MO_NC | OpFlags)
.addImm(0);
}
return ResultReg;
}

View File

@ -929,6 +929,12 @@ bool AArch64InstructionSelector::select(MachineInstr &I,
return false;
}
// FIXME: PR36018: Volatile loads in some cases are incorrectly selected by
// folding with an extend. Until we have a G_SEXTLOAD solution bail out if
// we hit one.
if (Opcode == TargetOpcode::G_LOAD && MemOp.isVolatile())
return false;
const unsigned PtrReg = I.getOperand(1).getReg();
#ifndef NDEBUG
const RegisterBank &PtrRB = *RBI.getRegBank(PtrReg, MRI, TRI);

View File

@ -189,15 +189,18 @@ AArch64Subtarget::ClassifyGlobalReference(const GlobalValue *GV,
if (TM.getCodeModel() == CodeModel::Large && isTargetMachO())
return AArch64II::MO_GOT;
unsigned Flags = GV->hasDLLImportStorageClass() ? AArch64II::MO_DLLIMPORT
: AArch64II::MO_NO_FLAG;
if (!TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
return AArch64II::MO_GOT;
return AArch64II::MO_GOT | Flags;
// The small code model's direct accesses use ADRP, which cannot
// necessarily produce the value 0 (if the code is above 4GB).
if (useSmallAddressing() && GV->hasExternalWeakLinkage())
return AArch64II::MO_GOT;
return AArch64II::MO_GOT | Flags;
return AArch64II::MO_NO_FLAG;
return Flags;
}
unsigned char AArch64Subtarget::classifyGlobalFunctionReference(

View File

@ -210,65 +210,73 @@ void SIInsertSkips::kill(MachineInstr &MI) {
switch (MI.getOperand(2).getImm()) {
case ISD::SETOEQ:
case ISD::SETEQ:
Opcode = AMDGPU::V_CMPX_EQ_F32_e32;
Opcode = AMDGPU::V_CMPX_EQ_F32_e64;
break;
case ISD::SETOGT:
case ISD::SETGT:
Opcode = AMDGPU::V_CMPX_LT_F32_e32;
Opcode = AMDGPU::V_CMPX_LT_F32_e64;
break;
case ISD::SETOGE:
case ISD::SETGE:
Opcode = AMDGPU::V_CMPX_LE_F32_e32;
Opcode = AMDGPU::V_CMPX_LE_F32_e64;
break;
case ISD::SETOLT:
case ISD::SETLT:
Opcode = AMDGPU::V_CMPX_GT_F32_e32;
Opcode = AMDGPU::V_CMPX_GT_F32_e64;
break;
case ISD::SETOLE:
case ISD::SETLE:
Opcode = AMDGPU::V_CMPX_GE_F32_e32;
Opcode = AMDGPU::V_CMPX_GE_F32_e64;
break;
case ISD::SETONE:
case ISD::SETNE:
Opcode = AMDGPU::V_CMPX_LG_F32_e32;
Opcode = AMDGPU::V_CMPX_LG_F32_e64;
break;
case ISD::SETO:
Opcode = AMDGPU::V_CMPX_O_F32_e32;
Opcode = AMDGPU::V_CMPX_O_F32_e64;
break;
case ISD::SETUO:
Opcode = AMDGPU::V_CMPX_U_F32_e32;
Opcode = AMDGPU::V_CMPX_U_F32_e64;
break;
case ISD::SETUEQ:
Opcode = AMDGPU::V_CMPX_NLG_F32_e32;
Opcode = AMDGPU::V_CMPX_NLG_F32_e64;
break;
case ISD::SETUGT:
Opcode = AMDGPU::V_CMPX_NGE_F32_e32;
Opcode = AMDGPU::V_CMPX_NGE_F32_e64;
break;
case ISD::SETUGE:
Opcode = AMDGPU::V_CMPX_NGT_F32_e32;
Opcode = AMDGPU::V_CMPX_NGT_F32_e64;
break;
case ISD::SETULT:
Opcode = AMDGPU::V_CMPX_NLE_F32_e32;
Opcode = AMDGPU::V_CMPX_NLE_F32_e64;
break;
case ISD::SETULE:
Opcode = AMDGPU::V_CMPX_NLT_F32_e32;
Opcode = AMDGPU::V_CMPX_NLT_F32_e64;
break;
case ISD::SETUNE:
Opcode = AMDGPU::V_CMPX_NEQ_F32_e32;
Opcode = AMDGPU::V_CMPX_NEQ_F32_e64;
break;
default:
llvm_unreachable("invalid ISD:SET cond code");
}
// TODO: Allow this:
if (!MI.getOperand(0).isReg() ||
!TRI->isVGPR(MBB.getParent()->getRegInfo(),
MI.getOperand(0).getReg()))
llvm_unreachable("SI_KILL operand should be a VGPR");
assert(MI.getOperand(0).isReg());
BuildMI(MBB, &MI, DL, TII->get(Opcode))
.add(MI.getOperand(1))
.add(MI.getOperand(0));
if (TRI->isVGPR(MBB.getParent()->getRegInfo(),
MI.getOperand(0).getReg())) {
Opcode = AMDGPU::getVOPe32(Opcode);
BuildMI(MBB, &MI, DL, TII->get(Opcode))
.add(MI.getOperand(1))
.add(MI.getOperand(0));
} else {
BuildMI(MBB, &MI, DL, TII->get(Opcode))
.addReg(AMDGPU::VCC, RegState::Define)
.addImm(0) // src0 modifiers
.add(MI.getOperand(1))
.addImm(0) // src1 modifiers
.add(MI.getOperand(0))
.addImm(0); // omod
}
break;
}
case AMDGPU::SI_KILL_I1_TERMINATOR: {

View File

@ -39,11 +39,11 @@ void X86IntelInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
const MCSubtargetInfo &STI) {
const MCInstrDesc &Desc = MII.get(MI->getOpcode());
uint64_t TSFlags = Desc.TSFlags;
unsigned Flags = MI->getFlags();
if (TSFlags & X86II::LOCK)
if ((TSFlags & X86II::LOCK) || (Flags & X86::IP_HAS_LOCK))
OS << "\tlock\t";
unsigned Flags = MI->getFlags();
if (Flags & X86::IP_HAS_REPEAT_NE)
OS << "\trepne\t";
else if (Flags & X86::IP_HAS_REPEAT)

View File

@ -31776,9 +31776,10 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
// Check all uses of the condition operand to check whether it will be
// consumed by non-BLEND instructions. Those may require that all bits
// are set properly.
for (SDNode *U : Cond->uses()) {
for (SDNode::use_iterator UI = Cond->use_begin(), UE = Cond->use_end();
UI != UE; ++UI) {
// TODO: Add other opcodes eventually lowered into BLEND.
if (U->getOpcode() != ISD::VSELECT)
if (UI->getOpcode() != ISD::VSELECT || UI.getOperandNo() != 0)
return SDValue();
}

View File

@ -142,10 +142,11 @@ recordConditions(const CallSite &CS, BasicBlock *Pred,
recordCondition(CS, Pred, CS.getInstruction()->getParent(), Conditions);
BasicBlock *From = Pred;
BasicBlock *To = Pred;
SmallPtrSet<BasicBlock *, 4> Visited = {From};
SmallPtrSet<BasicBlock *, 4> Visited;
while (!Visited.count(From->getSinglePredecessor()) &&
(From = From->getSinglePredecessor())) {
recordCondition(CS, From, To, Conditions);
Visited.insert(From);
To = From;
}
}

View File

@ -14,6 +14,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/DivergenceAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Analysis/RegionIterator.h"
#include "llvm/Analysis/RegionPass.h"
@ -176,8 +177,9 @@ class StructurizeCFG : public RegionPass {
Region *ParentRegion;
DominatorTree *DT;
LoopInfo *LI;
std::deque<RegionNode *> Order;
SmallVector<RegionNode *, 8> Order;
BBSet Visited;
BBPhiMap DeletedPhis;
@ -202,7 +204,7 @@ class StructurizeCFG : public RegionPass {
void gatherPredicates(RegionNode *N);
void analyzeNode(RegionNode *N);
void collectInfos();
void insertConditions(bool Loops);
@ -256,6 +258,7 @@ class StructurizeCFG : public RegionPass {
AU.addRequired<DivergenceAnalysis>();
AU.addRequiredID(LowerSwitchID);
AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<LoopInfoWrapperPass>();
AU.addPreserved<DominatorTreeWrapperPass>();
RegionPass::getAnalysisUsage(AU);
@ -289,17 +292,55 @@ bool StructurizeCFG::doInitialization(Region *R, RGPassManager &RGM) {
/// \brief Build up the general order of nodes
void StructurizeCFG::orderNodes() {
assert(Visited.empty());
assert(Predicates.empty());
assert(Loops.empty());
assert(LoopPreds.empty());
ReversePostOrderTraversal<Region*> RPOT(ParentRegion);
SmallDenseMap<Loop*, unsigned, 8> LoopBlocks;
// This must be RPO order for the back edge detection to work
for (RegionNode *RN : ReversePostOrderTraversal<Region*>(ParentRegion)) {
// FIXME: Is there a better order to use for structurization?
Order.push_back(RN);
analyzeNode(RN);
// The reverse post-order traversal of the list gives us an ordering close
// to what we want. The only problem with it is that sometimes backedges
// for outer loops will be visited before backedges for inner loops.
for (RegionNode *RN : RPOT) {
BasicBlock *BB = RN->getEntry();
Loop *Loop = LI->getLoopFor(BB);
++LoopBlocks[Loop];
}
unsigned CurrentLoopDepth = 0;
Loop *CurrentLoop = nullptr;
for (auto I = RPOT.begin(), E = RPOT.end(); I != E; ++I) {
BasicBlock *BB = (*I)->getEntry();
unsigned LoopDepth = LI->getLoopDepth(BB);
if (is_contained(Order, *I))
continue;
if (LoopDepth < CurrentLoopDepth) {
// Make sure we have visited all blocks in this loop before moving back to
// the outer loop.
auto LoopI = I;
while (unsigned &BlockCount = LoopBlocks[CurrentLoop]) {
LoopI++;
BasicBlock *LoopBB = (*LoopI)->getEntry();
if (LI->getLoopFor(LoopBB) == CurrentLoop) {
--BlockCount;
Order.push_back(*LoopI);
}
}
}
CurrentLoop = LI->getLoopFor(BB);
if (CurrentLoop)
LoopBlocks[CurrentLoop]--;
CurrentLoopDepth = LoopDepth;
Order.push_back(*I);
}
// This pass originally used a post-order traversal and then operated on
// the list in reverse. Now that we are using a reverse post-order traversal
// rather than re-working the whole pass to operate on the list in order,
// we just reverse the list and continue to operate on it in reverse.
std::reverse(Order.begin(), Order.end());
}
/// \brief Determine the end of the loops
@ -425,19 +466,32 @@ void StructurizeCFG::gatherPredicates(RegionNode *N) {
}
/// \brief Collect various loop and predicate infos
void StructurizeCFG::analyzeNode(RegionNode *RN) {
DEBUG(dbgs() << "Visiting: "
<< (RN->isSubRegion() ? "SubRegion with entry: " : "")
<< RN->getEntry()->getName() << '\n');
void StructurizeCFG::collectInfos() {
// Reset predicate
Predicates.clear();
// Analyze all the conditions leading to a node
gatherPredicates(RN);
// and loop infos
Loops.clear();
LoopPreds.clear();
// Remember that we've seen this node
Visited.insert(RN->getEntry());
// Reset the visited nodes
Visited.clear();
// Find the last back edges
analyzeLoops(RN);
for (RegionNode *RN : reverse(Order)) {
DEBUG(dbgs() << "Visiting: "
<< (RN->isSubRegion() ? "SubRegion with entry: " : "")
<< RN->getEntry()->getName() << " Loop Depth: "
<< LI->getLoopDepth(RN->getEntry()) << "\n");
// Analyze all the conditions leading to a node
gatherPredicates(RN);
// Remember that we've seen this node
Visited.insert(RN->getEntry());
// Find the last back edges
analyzeLoops(RN);
}
}
/// \brief Insert the missing branch conditions
@ -610,7 +664,7 @@ void StructurizeCFG::changeExit(RegionNode *Node, BasicBlock *NewExit,
BasicBlock *StructurizeCFG::getNextFlow(BasicBlock *Dominator) {
LLVMContext &Context = Func->getContext();
BasicBlock *Insert = Order.empty() ? ParentRegion->getExit() :
Order.front()->getEntry();
Order.back()->getEntry();
BasicBlock *Flow = BasicBlock::Create(Context, FlowBlockName,
Func, Insert);
DT->addNewBlock(Flow, Dominator);
@ -690,8 +744,7 @@ bool StructurizeCFG::isPredictableTrue(RegionNode *Node) {
/// Take one node from the order vector and wire it up
void StructurizeCFG::wireFlow(bool ExitUseAllowed,
BasicBlock *LoopEnd) {
RegionNode *Node = Order.front();
Order.pop_front();
RegionNode *Node = Order.pop_back_val();
Visited.insert(Node->getEntry());
if (isPredictableTrue(Node)) {
@ -715,7 +768,7 @@ void StructurizeCFG::wireFlow(bool ExitUseAllowed,
PrevNode = Node;
while (!Order.empty() && !Visited.count(LoopEnd) &&
dominatesPredicates(Entry, Order.front())) {
dominatesPredicates(Entry, Order.back())) {
handleLoops(false, LoopEnd);
}
@ -726,7 +779,7 @@ void StructurizeCFG::wireFlow(bool ExitUseAllowed,
void StructurizeCFG::handleLoops(bool ExitUseAllowed,
BasicBlock *LoopEnd) {
RegionNode *Node = Order.front();
RegionNode *Node = Order.back();
BasicBlock *LoopStart = Node->getEntry();
if (!Loops.count(LoopStart)) {
@ -871,9 +924,10 @@ bool StructurizeCFG::runOnRegion(Region *R, RGPassManager &RGM) {
ParentRegion = R;
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
orderNodes();
collectInfos();
createFlow();
insertConditions(false);
insertConditions(true);

View File

@ -25,6 +25,7 @@
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
@ -536,13 +537,23 @@ Optional<Metadata *> MDNodeMapper::tryToMapOperand(const Metadata *Op) {
return None;
}
static Metadata *cloneOrBuildODR(const MDNode &N) {
auto *CT = dyn_cast<DICompositeType>(&N);
// If ODR type uniquing is enabled, we would have uniqued composite types
// with identifiers during bitcode reading, so we can just use CT.
if (CT && CT->getContext().isODRUniquingDebugTypes() &&
CT->getIdentifier() != "")
return const_cast<DICompositeType *>(CT);
return MDNode::replaceWithDistinct(N.clone());
}
MDNode *MDNodeMapper::mapDistinctNode(const MDNode &N) {
assert(N.isDistinct() && "Expected a distinct node");
assert(!M.getVM().getMappedMD(&N) && "Expected an unmapped node");
DistinctWorklist.push_back(cast<MDNode>(
(M.Flags & RF_MoveDistinctMDs)
? M.mapToSelf(&N)
: M.mapToMetadata(&N, MDNode::replaceWithDistinct(N.clone()))));
DistinctWorklist.push_back(
cast<MDNode>((M.Flags & RF_MoveDistinctMDs)
? M.mapToSelf(&N)
: M.mapToMetadata(&N, cloneOrBuildODR(N))));
return DistinctWorklist.back();
}

View File

@ -354,4 +354,12 @@ def warn_drv_fine_grained_bitfield_accesses_ignored : Warning<
def note_drv_verify_prefix_spelling : Note<
"-verify prefixes must start with a letter and contain only alphanumeric"
" characters, hyphens, and underscores">;
def warn_drv_experimental_isel_incomplete : Warning<
"-fexperimental-isel support for the '%0' architecture is incomplete">,
InGroup<ExperimentalISel>;
def warn_drv_experimental_isel_incomplete_opt : Warning<
"-fexperimental-isel support is incomplete for this architecture at the current optimization level">,
InGroup<ExperimentalISel>;
}

View File

@ -985,3 +985,6 @@ def UnknownArgument : DiagGroup<"unknown-argument">;
// A warning group for warnings about code that clang accepts when
// compiling OpenCL C/C++ but which is not compatible with the SPIR spec.
def SpirCompat : DiagGroup<"spir-compat">;
// Warning for the experimental-isel options.
def ExperimentalISel : DiagGroup<"experimental-isel">;

View File

@ -1031,6 +1031,8 @@ def finline_functions : Flag<["-"], "finline-functions">, Group<f_clang_Group>,
def finline_hint_functions: Flag<["-"], "finline-hint-functions">, Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Inline functions which are (explicitly or implicitly) marked inline">;
def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>;
def fexperimental_isel : Flag<["-"], "fexperimental-isel">, Group<f_clang_Group>,
HelpText<"Enables the experimental global instruction selector">;
def fexperimental_new_pass_manager : Flag<["-"], "fexperimental-new-pass-manager">,
Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Enables an experimental new pass manager in LLVM.">;
@ -1237,6 +1239,8 @@ def fno_exceptions : Flag<["-"], "fno-exceptions">, Group<f_Group>;
def fno_gnu_keywords : Flag<["-"], "fno-gnu-keywords">, Group<f_Group>, Flags<[CC1Option]>;
def fno_inline_functions : Flag<["-"], "fno-inline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>;
def fno_inline : Flag<["-"], "fno-inline">, Group<f_clang_Group>, Flags<[CC1Option]>;
def fno_experimental_isel : Flag<["-"], "fno-experimental-isel">, Group<f_clang_Group>,
HelpText<"Disables the experimental global instruction selector">;
def fno_experimental_new_pass_manager : Flag<["-"], "fno-experimental-new-pass-manager">,
Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Disables an experimental new pass manager in LLVM.">;

View File

@ -4639,6 +4639,37 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fwhole-program-vtables");
}
if (Arg *A = Args.getLastArg(options::OPT_fexperimental_isel,
options::OPT_fno_experimental_isel)) {
CmdArgs.push_back("-mllvm");
if (A->getOption().matches(options::OPT_fexperimental_isel)) {
CmdArgs.push_back("-global-isel=1");
// GISel is on by default on AArch64 -O0, so don't bother adding
// the fallback remarks for it. Other combinations will add a warning of
// some kind.
bool IsArchSupported = Triple.getArch() == llvm::Triple::aarch64;
bool IsOptLevelSupported = false;
Arg *A = Args.getLastArg(options::OPT_O_Group);
if (Triple.getArch() == llvm::Triple::aarch64) {
if (!A || A->getOption().matches(options::OPT_O0))
IsOptLevelSupported = true;
}
if (!IsArchSupported || !IsOptLevelSupported) {
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("-global-isel-abort=2");
if (!IsArchSupported)
D.Diag(diag::warn_drv_experimental_isel_incomplete) << Triple.getArchName();
else
D.Diag(diag::warn_drv_experimental_isel_incomplete_opt);
}
} else {
CmdArgs.push_back("-global-isel=0");
}
}
// Finally add the compile command to the compilation.
if (Args.hasArg(options::OPT__SLASH_fallback) &&
Output.getType() == types::TY_Object &&

View File

@ -46,7 +46,7 @@ static void handleHVXWarnings(const Driver &D, const ArgList &Args) {
// Handle the unsupported values passed to mhvx-length.
if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
StringRef Val = A->getValue();
if (Val != "64B" && Val != "128B")
if (!Val.equals_lower("64b") && !Val.equals_lower("128b"))
D.Diag(diag::err_drv_unsupported_option_argument)
<< A->getOption().getName() << Val;
}

View File

@ -47,6 +47,7 @@
using namespace llvm;
using namespace llvm::ELF;
using namespace llvm::object;
using namespace llvm::support;
using namespace llvm::support::endian;
using namespace lld;
@ -357,7 +358,7 @@ static uint64_t scanCortexA53Errata843419(InputSection *IS, uint64_t &Off,
uint64_t PatchOff = 0;
const uint8_t *Buf = IS->Data.begin();
const uint32_t *InstBuf = reinterpret_cast<const uint32_t *>(Buf + Off);
const ulittle32_t *InstBuf = reinterpret_cast<const ulittle32_t *>(Buf + Off);
uint32_t Instr1 = *InstBuf++;
uint32_t Instr2 = *InstBuf++;
uint32_t Instr3 = *InstBuf++;

View File

@ -45,8 +45,9 @@ struct PhdrEntry {
OutputSection *LastSec = nullptr;
bool HasLMA = false;
// True if any of the sections in this program header as a LMA specified via
// linker script: AT(addr).
// True if one of the sections in this program header has a LMA specified via
// linker script: AT(addr). We never allow 2 or more sections with LMA in the
// same program header.
bool ASectionHasLMA = false;
uint64_t LMAOffset = 0;

View File

@ -8,4 +8,4 @@
#define CLANG_VENDOR "FreeBSD "
#define SVN_REVISION "323338"
#define SVN_REVISION "323948"

View File

@ -4,5 +4,5 @@
#define LLD_VERSION_STRING "6.0.0"
#define LLD_VERSION_MAJOR 6
#define LLD_VERSION_MINOR 0
#define LLD_REVISION_STRING "323338"
#define LLD_REVISION_STRING "323948"
#define LLD_REPOSITORY_STRING "FreeBSD"

View File

@ -1,2 +1,2 @@
/* $FreeBSD$ */
#define LLVM_REVISION "svn-r323338"
#define LLVM_REVISION "svn-r323948"