summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-08-29 17:50:33 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-08-29 17:50:33 +0000
commit8568f9cb5af587ccee4088af3e2d617b3c30d403 (patch)
tree38ef3950af2e183a6c1c23947e35e837fce15a9a /lib
parentd0a9cbdae159210824ddf2da138e2dcaecbe1cd4 (diff)
Notes
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/CodeGenPrepare.cpp56
-rw-r--r--lib/CodeGen/GlobalISel/IRTranslator.cpp2
-rw-r--r--lib/IR/DebugInfo.cpp2
-rw-r--r--lib/MC/MCExpr.cpp16
-rw-r--r--lib/MC/MCParser/AsmParser.cpp24
-rw-r--r--lib/Support/Path.cpp10
-rw-r--r--lib/Support/Windows/Path.inc2
-rw-r--r--lib/Target/AArch64/AArch64SystemOperands.td15
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp14
-rw-r--r--lib/Target/X86/MCTargetDesc/X86MCExpr.h7
-rw-r--r--lib/Transforms/Utils/BypassSlowDivision.cpp9
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