diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-08-29 17:50:33 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-08-29 17:50:33 +0000 |
commit | 8568f9cb5af587ccee4088af3e2d617b3c30d403 (patch) | |
tree | 38ef3950af2e183a6c1c23947e35e837fce15a9a /lib | |
parent | d0a9cbdae159210824ddf2da138e2dcaecbe1cd4 (diff) |
Notes
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/CodeGenPrepare.cpp | 56 | ||||
-rw-r--r-- | lib/CodeGen/GlobalISel/IRTranslator.cpp | 2 | ||||
-rw-r--r-- | lib/IR/DebugInfo.cpp | 2 | ||||
-rw-r--r-- | lib/MC/MCExpr.cpp | 16 | ||||
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 24 | ||||
-rw-r--r-- | lib/Support/Path.cpp | 10 | ||||
-rw-r--r-- | lib/Support/Windows/Path.inc | 2 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64SystemOperands.td | 15 | ||||
-rw-r--r-- | lib/Target/X86/AsmParser/X86AsmParser.cpp | 14 | ||||
-rw-r--r-- | lib/Target/X86/MCTargetDesc/X86MCExpr.h | 7 | ||||
-rw-r--r-- | lib/Transforms/Utils/BypassSlowDivision.cpp | 9 |
11 files changed, 125 insertions, 32 deletions
diff --git a/lib/CodeGen/CodeGenPrepare.cpp b/lib/CodeGen/CodeGenPrepare.cpp index c41beb094604e..be685b26a9ea2 100644 --- a/lib/CodeGen/CodeGenPrepare.cpp +++ b/lib/CodeGen/CodeGenPrepare.cpp @@ -223,8 +223,17 @@ static cl::opt<bool> namespace { +enum ExtType { + ZeroExtension, // Zero extension has been seen. + SignExtension, // Sign extension has been seen. + BothExtension // This extension type is used if we saw sext after + // ZeroExtension had been set, or if we saw zext after + // SignExtension had been set. It makes the type + // information of a promoted instruction invalid. +}; + using SetOfInstrs = SmallPtrSet<Instruction *, 16>; -using TypeIsSExt = PointerIntPair<Type *, 1, bool>; +using TypeIsSExt = PointerIntPair<Type *, 2, ExtType>; using InstrToOrigTy = DenseMap<Instruction *, TypeIsSExt>; using SExts = SmallVector<Instruction *, 16>; using ValueToSExts = DenseMap<Value *, SExts>; @@ -3277,6 +3286,41 @@ namespace { /// Hepler class to perform type promotion. class TypePromotionHelper { + /// Utility function to add a promoted instruction \p ExtOpnd to + /// \p PromotedInsts and record the type of extension we have seen. + static void addPromotedInst(InstrToOrigTy &PromotedInsts, + Instruction *ExtOpnd, + bool IsSExt) { + ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension; + InstrToOrigTy::iterator It = PromotedInsts.find(ExtOpnd); + if (It != PromotedInsts.end()) { + // If the new extension is same as original, the information in + // PromotedInsts[ExtOpnd] is still correct. + if (It->second.getInt() == ExtTy) + return; + + // Now the new extension is different from old extension, we make + // the type information invalid by setting extension type to + // BothExtension. + ExtTy = BothExtension; + } + PromotedInsts[ExtOpnd] = TypeIsSExt(ExtOpnd->getType(), ExtTy); + } + + /// Utility function to query the original type of instruction \p Opnd + /// with a matched extension type. If the extension doesn't match, we + /// cannot use the information we had on the original type. + /// BothExtension doesn't match any extension type. + static const Type *getOrigType(const InstrToOrigTy &PromotedInsts, + Instruction *Opnd, + bool IsSExt) { + ExtType ExtTy = IsSExt ? SignExtension : ZeroExtension; + InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd); + if (It != PromotedInsts.end() && It->second.getInt() == ExtTy) + return It->second.getPointer(); + return nullptr; + } + /// Utility function to check whether or not a sign or zero extension /// of \p Inst with \p ConsideredExtType can be moved through \p Inst by /// either using the operands of \p Inst or promoting \p Inst. @@ -3465,10 +3509,9 @@ bool TypePromotionHelper::canGetThrough(const Instruction *Inst, // I.e., check that trunc just drops extended bits of the same kind of // the extension. // #1 get the type of the operand and check the kind of the extended bits. - const Type *OpndType; - InstrToOrigTy::const_iterator It = PromotedInsts.find(Opnd); - if (It != PromotedInsts.end() && It->second.getInt() == IsSExt) - OpndType = It->second.getPointer(); + const Type *OpndType = getOrigType(PromotedInsts, Opnd, IsSExt); + if (OpndType) + ; else if ((IsSExt && isa<SExtInst>(Opnd)) || (!IsSExt && isa<ZExtInst>(Opnd))) OpndType = Opnd->getOperand(0)->getType(); else @@ -3596,8 +3639,7 @@ Value *TypePromotionHelper::promoteOperandForOther( // Remember the original type of the instruction before promotion. // This is useful to know that the high bits are sign extended bits. - PromotedInsts.insert(std::pair<Instruction *, TypeIsSExt>( - ExtOpnd, TypeIsSExt(ExtOpnd->getType(), IsSExt))); + addPromotedInst(PromotedInsts, ExtOpnd, IsSExt); // Step #1. TPT.mutateType(ExtOpnd, Ext->getType()); // Step #2. diff --git a/lib/CodeGen/GlobalISel/IRTranslator.cpp b/lib/CodeGen/GlobalISel/IRTranslator.cpp index 80da50562d323..75496fba04493 100644 --- a/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1435,6 +1435,8 @@ void IRTranslator::finishPendingPhis() { bool IRTranslator::valueIsSplit(const Value &V, SmallVectorImpl<uint64_t> *Offsets) { SmallVector<LLT, 4> SplitTys; + if (Offsets && !Offsets->empty()) + Offsets->clear(); computeValueLLTs(*DL, *V.getType(), SplitTys, Offsets); return SplitTys.size() > 1; } diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp index 77585ee30cd80..165c881c13e70 100644 --- a/lib/IR/DebugInfo.cpp +++ b/lib/IR/DebugInfo.cpp @@ -1329,7 +1329,7 @@ LLVMMetadataRef LLVMDIBuilderCreateParameterVariable( size_t NameLen, unsigned ArgNo, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, LLVMBool AlwaysPreserve, LLVMDIFlags Flags) { return wrap(unwrap(Builder)->createParameterVariable( - unwrap<DIScope>(Scope), Name, ArgNo, unwrap<DIFile>(File), + unwrap<DIScope>(Scope), {Name, NameLen}, ArgNo, unwrap<DIFile>(File), LineNo, unwrap<DIType>(Ty), AlwaysPreserve, map_from_llvmDIFlags(Flags))); } diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index 0694a8fa620e5..a4c99a0c1c152 100644 --- a/lib/MC/MCExpr.cpp +++ b/lib/MC/MCExpr.cpp @@ -750,8 +750,22 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, if (!ABE->getLHS()->evaluateAsRelocatableImpl(LHSValue, Asm, Layout, Fixup, Addrs, InSet) || !ABE->getRHS()->evaluateAsRelocatableImpl(RHSValue, Asm, Layout, Fixup, - Addrs, InSet)) + Addrs, InSet)) { + // Check if both are Target Expressions, see if we can compare them. + if (const MCTargetExpr *L = dyn_cast<MCTargetExpr>(ABE->getLHS())) + if (const MCTargetExpr *R = cast<MCTargetExpr>(ABE->getRHS())) { + switch (ABE->getOpcode()) { + case MCBinaryExpr::EQ: + Res = MCValue::get((L->isEqualTo(R)) ? -1 : 0); + return true; + case MCBinaryExpr::NE: + Res = MCValue::get((R->isEqualTo(R)) ? 0 : -1); + return true; + default: {} + } + } return false; + } // We only support a few operations on non-constant expressions, handle // those first. diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 39a760826d96d..501a1cccf60e4 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -337,7 +337,7 @@ private: StringRef parseStringToComma(); bool parseAssignment(StringRef Name, bool allow_redef, - bool NoDeadStrip = false, bool AllowExtendedExpr = false); + bool NoDeadStrip = false); unsigned getBinOpPrecedence(AsmToken::TokenKind K, MCBinaryExpr::Opcode &Kind); @@ -1363,7 +1363,8 @@ void AsmParser::altMacroString(StringRef AltMacroStr,std::string &Res) { bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) { // Parse the expression. Res = nullptr; - if (parsePrimaryExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc)) + if (getTargetParser().parsePrimaryExpr(Res, EndLoc) || + parseBinOpRHS(1, Res, EndLoc)) return true; // As a special case, we support 'a op b @ modifier' by rewriting the @@ -1617,7 +1618,7 @@ bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, // Eat the next primary expression. const MCExpr *RHS; - if (parsePrimaryExpr(RHS, EndLoc)) + if (getTargetParser().parsePrimaryExpr(RHS, EndLoc)) return true; // If BinOp binds less tightly with RHS than the operator after RHS, let @@ -1826,7 +1827,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, // identifier '=' ... -> assignment statement Lex(); - return parseAssignment(IDVal, true, /*NoDeadStrip*/ false, /*AllowExtendedExpr*/true); + return parseAssignment(IDVal, true); default: // Normal instruction or directive. break; @@ -2766,11 +2767,11 @@ void AsmParser::handleMacroExit() { } bool AsmParser::parseAssignment(StringRef Name, bool allow_redef, - bool NoDeadStrip, bool AllowExtendedExpr) { + bool NoDeadStrip) { MCSymbol *Sym; const MCExpr *Value; if (MCParserUtils::parseAssignmentExpression(Name, allow_redef, *this, Sym, - Value, AllowExtendedExpr)) + Value)) return true; if (!Sym) { @@ -5839,17 +5840,12 @@ static bool isSymbolUsedInExpression(const MCSymbol *Sym, const MCExpr *Value) { bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Sym, - const MCExpr *&Value, bool AllowExtendedExpr) { + const MCExpr *&Value) { // FIXME: Use better location, we should use proper tokens. SMLoc EqualLoc = Parser.getTok().getLoc(); - SMLoc EndLoc; - if (AllowExtendedExpr) { - if (Parser.getTargetParser().parseAssignmentExpression(Value, EndLoc)) { - return Parser.TokError("missing expression"); - } - } else if (Parser.parseExpression(Value, EndLoc)) - return Parser.TokError("missing expression"); + if (Parser.parseExpression(Value)) + return Parser.TokError("missing expression"); // Note: we don't count b as used in "a = b". This is to allow // a = b diff --git a/lib/Support/Path.cpp b/lib/Support/Path.cpp index 098230290ed28..768a819c8d05b 100644 --- a/lib/Support/Path.cpp +++ b/lib/Support/Path.cpp @@ -1150,8 +1150,16 @@ Error TempFile::keep(const Twine &Name) { // If we can't cancel the delete don't rename. auto H = reinterpret_cast<HANDLE>(_get_osfhandle(FD)); std::error_code RenameEC = setDeleteDisposition(H, false); - if (!RenameEC) + if (!RenameEC) { RenameEC = rename_fd(FD, Name); + // If rename failed because it's cross-device, copy instead + if (RenameEC == + std::error_code(ERROR_NOT_SAME_DEVICE, std::system_category())) { + RenameEC = copy_file(TmpName, Name); + setDeleteDisposition(H, true); + } + } + // If we can't rename, discard the temporary file. if (RenameEC) setDeleteDisposition(H, true); diff --git a/lib/Support/Windows/Path.inc b/lib/Support/Windows/Path.inc index b64b013d7407d..f425d607af47f 100644 --- a/lib/Support/Windows/Path.inc +++ b/lib/Support/Windows/Path.inc @@ -450,7 +450,7 @@ static std::error_code rename_handle(HANDLE FromHandle, const Twine &To) { if (std::error_code EC2 = realPathFromHandle(FromHandle, WideFrom)) return EC2; if (::MoveFileExW(WideFrom.begin(), WideTo.begin(), - MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED)) + MOVEFILE_REPLACE_EXISTING)) return std::error_code(); return mapWindowsError(GetLastError()); } diff --git a/lib/Target/AArch64/AArch64SystemOperands.td b/lib/Target/AArch64/AArch64SystemOperands.td index 8acd32533eea0..dbc4deaf3f9f3 100644 --- a/lib/Target/AArch64/AArch64SystemOperands.td +++ b/lib/Target/AArch64/AArch64SystemOperands.td @@ -576,6 +576,12 @@ def : ROSysReg<"ICH_VTR_EL2", 0b11, 0b100, 0b1100, 0b1011, 0b001>; def : ROSysReg<"ICH_EISR_EL2", 0b11, 0b100, 0b1100, 0b1011, 0b011>; def : ROSysReg<"ICH_ELRSR_EL2", 0b11, 0b100, 0b1100, 0b1011, 0b101>; +// SVE control registers +// Op0 Op1 CRn CRm Op2 +let Requires = [{ {AArch64::FeatureSVE} }] in { +def : ROSysReg<"ID_AA64ZFR0_EL1", 0b11, 0b000, 0b0000, 0b0100, 0b100>; +} + // v8.1a "Limited Ordering Regions" extension-specific system register // Op0 Op1 CRn CRm Op2 let Requires = [{ {AArch64::HasV8_1aOps} }] in @@ -1311,6 +1317,15 @@ def : RWSysReg<"VNCR_EL2", 0b11, 0b100, 0b0010, 0b0010, 0b000>; } // HasV8_4aOps +// SVE control registers +// Op0 Op1 CRn CRm Op2 +let Requires = [{ {AArch64::FeatureSVE} }] in { +def : RWSysReg<"ZCR_EL1", 0b11, 0b000, 0b0001, 0b0010, 0b000>; +def : RWSysReg<"ZCR_EL2", 0b11, 0b100, 0b0001, 0b0010, 0b000>; +def : RWSysReg<"ZCR_EL3", 0b11, 0b110, 0b0001, 0b0010, 0b000>; +def : RWSysReg<"ZCR_EL12", 0b11, 0b101, 0b0001, 0b0010, 0b000>; +} + // Cyclone specific system registers // Op0 Op1 CRn CRm Op2 let Requires = [{ {AArch64::ProcCyclone} }] in diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index fafbed0bd9351..b02e4d80fbba2 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -955,7 +955,7 @@ public: void SetFrameRegister(unsigned RegNo) override; - bool parseAssignmentExpression(const MCExpr *&Res, SMLoc &EndLoc) override; + bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override; bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands) override; @@ -2260,15 +2260,17 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg, return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd); } -// Parse either a standard expression or a register. -bool X86AsmParser::parseAssignmentExpression(const MCExpr *&Res, - SMLoc &EndLoc) { +// Parse either a standard primary expression or a register. +bool X86AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { MCAsmParser &Parser = getParser(); - if (Parser.parseExpression(Res, EndLoc)) { + if (Parser.parsePrimaryExpr(Res, EndLoc)) { SMLoc StartLoc = Parser.getTok().getLoc(); // Normal Expression parse fails, check if it could be a register. unsigned RegNo; - if (Parser.getTargetParser().ParseRegister(RegNo, StartLoc, EndLoc)) + bool TryRegParse = + getTok().is(AsmToken::Percent) || + (isParsingIntelSyntax() && getTok().is(AsmToken::Identifier)); + if (!TryRegParse || ParseRegister(RegNo, StartLoc, EndLoc)) return true; // Clear previous parse error and return correct expression. Parser.clearPendingErrors(); diff --git a/lib/Target/X86/MCTargetDesc/X86MCExpr.h b/lib/Target/X86/MCTargetDesc/X86MCExpr.h index f1438cd249602..1070f70468fa2 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCExpr.h +++ b/lib/Target/X86/MCTargetDesc/X86MCExpr.h @@ -48,7 +48,7 @@ public: /// @} void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override { - if (MAI->getAssemblerDialect() == 0) + if (!MAI || MAI->getAssemblerDialect() == 0) OS << '%'; OS << X86ATTInstPrinter::getRegisterName(RegNo); } @@ -59,6 +59,11 @@ public: } // Register values should be inlined as they are not valid .set expressions. bool inlineAssignedExpr() const override { return true; } + bool isEqualTo(const MCExpr *X) const override { + if (auto *E = dyn_cast<X86MCExpr>(X)) + return getRegNo() == E->getRegNo(); + return false; + } void visitUsedExpr(MCStreamer &Streamer) const override{}; MCFragment *findAssociatedFragment() const override { return nullptr; } diff --git a/lib/Transforms/Utils/BypassSlowDivision.cpp b/lib/Transforms/Utils/BypassSlowDivision.cpp index 05512a6dff3e5..e7828af648a91 100644 --- a/lib/Transforms/Utils/BypassSlowDivision.cpp +++ b/lib/Transforms/Utils/BypassSlowDivision.cpp @@ -388,6 +388,15 @@ Optional<QuotRemPair> FastDivInsertionTask::insertFastDivAndRem() { return None; } + // After Constant Hoisting pass, long constants may be represented as + // bitcast instructions. As a result, some constants may look like an + // instruction at first, and an additional check is necessary to find out if + // an operand is actually a constant. + if (auto *BCI = dyn_cast<BitCastInst>(Divisor)) + if (BCI->getParent() == SlowDivOrRem->getParent() && + isa<ConstantInt>(BCI->getOperand(0))) + return None; + if (DividendShort && !isSignedOp()) { // If the division is unsigned and Dividend is known to be short, then // either |