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:
commit
842d113b5c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=328753
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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(
|
||||
|
@ -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: {
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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>;
|
||||
}
|
||||
|
@ -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">;
|
||||
|
@ -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.">;
|
||||
|
@ -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 &&
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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++;
|
||||
|
@ -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;
|
||||
|
@ -8,4 +8,4 @@
|
||||
|
||||
#define CLANG_VENDOR "FreeBSD "
|
||||
|
||||
#define SVN_REVISION "323338"
|
||||
#define SVN_REVISION "323948"
|
||||
|
@ -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"
|
||||
|
@ -1,2 +1,2 @@
|
||||
/* $FreeBSD$ */
|
||||
#define LLVM_REVISION "svn-r323338"
|
||||
#define LLVM_REVISION "svn-r323948"
|
||||
|
Loading…
Reference in New Issue
Block a user