aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-04 22:11:11 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-04 22:11:11 +0000
commitc82ad72f63369bc462e59458f09960d66daa58a9 (patch)
tree58bc455a8d052220f9ae11e65d6f06d671a7a4c4 /lib/CodeGen
parentb915e9e0fc85ba6f398b3fab0db6a81a8913af94 (diff)
downloadsrc-c82ad72f63369bc462e59458f09960d66daa58a9.tar.gz
src-c82ad72f63369bc462e59458f09960d66daa58a9.zip
Vendor import of llvm trunk r291012:vendor/llvm/llvm-trunk-r291012
Notes
Notes: svn path=/vendor/llvm/dist/; revision=311315 svn path=/vendor/llvm/llvm-trunk-r291012/; revision=311316; tag=vendor/llvm/llvm-trunk-r291012
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/Analysis.cpp26
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp57
-rw-r--r--lib/CodeGen/InlineSpiller.cpp8
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp18
4 files changed, 74 insertions, 35 deletions
diff --git a/lib/CodeGen/Analysis.cpp b/lib/CodeGen/Analysis.cpp
index 0678bce449ed..79ecc4308fe7 100644
--- a/lib/CodeGen/Analysis.cpp
+++ b/lib/CodeGen/Analysis.cpp
@@ -272,28 +272,10 @@ static const Value *getNoopInput(const Value *V,
TLI.allowTruncateForTailCall(Op->getType(), I->getType())) {
DataBits = std::min(DataBits, I->getType()->getPrimitiveSizeInBits());
NoopInput = Op;
- } else if (isa<CallInst>(I)) {
- // Look through call (skipping callee)
- for (User::const_op_iterator i = I->op_begin(), e = I->op_end() - 1;
- i != e; ++i) {
- unsigned attrInd = i - I->op_begin() + 1;
- if (cast<CallInst>(I)->paramHasAttr(attrInd, Attribute::Returned) &&
- isNoopBitcast((*i)->getType(), I->getType(), TLI)) {
- NoopInput = *i;
- break;
- }
- }
- } else if (isa<InvokeInst>(I)) {
- // Look through invoke (skipping BB, BB, Callee)
- for (User::const_op_iterator i = I->op_begin(), e = I->op_end() - 3;
- i != e; ++i) {
- unsigned attrInd = i - I->op_begin() + 1;
- if (cast<InvokeInst>(I)->paramHasAttr(attrInd, Attribute::Returned) &&
- isNoopBitcast((*i)->getType(), I->getType(), TLI)) {
- NoopInput = *i;
- break;
- }
- }
+ } else if (auto CS = ImmutableCallSite(I)) {
+ const Value *ReturnedOp = CS.getReturnedArgOperand();
+ if (ReturnedOp && isNoopBitcast(ReturnedOp->getType(), I->getType(), TLI))
+ NoopInput = ReturnedOp;
} else if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(V)) {
// Value may come from either the aggregate or the scalar
ArrayRef<unsigned> InsertLoc = IVI->getIndices();
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index de0a4f0befa1..5f15ac1d503b 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -37,6 +37,8 @@
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/MCValue.h"
@@ -2610,6 +2612,61 @@ AsmPrinterHandler::~AsmPrinterHandler() {}
void AsmPrinterHandler::markFunctionEnd() {}
+// In the binary's "xray_instr_map" section, an array of these function entries
+// describes each instrumentation point. When XRay patches your code, the index
+// into this table will be given to your handler as a patch point identifier.
+void AsmPrinter::XRayFunctionEntry::emit(int Bytes, MCStreamer *Out,
+ const MCSymbol *CurrentFnSym) const {
+ Out->EmitSymbolValue(Sled, Bytes);
+ Out->EmitSymbolValue(CurrentFnSym, Bytes);
+ auto Kind8 = static_cast<uint8_t>(Kind);
+ Out->EmitBytes(StringRef(reinterpret_cast<const char *>(&Kind8), 1));
+ Out->EmitBytes(
+ StringRef(reinterpret_cast<const char *>(&AlwaysInstrument), 1));
+ Out->EmitZeros(2 * Bytes - 2); // Pad the previous two entries
+}
+
+void AsmPrinter::emitXRayTable() {
+ if (Sleds.empty())
+ return;
+
+ auto PrevSection = OutStreamer->getCurrentSectionOnly();
+ auto Fn = MF->getFunction();
+ MCSection *Section = nullptr;
+ if (MF->getSubtarget().getTargetTriple().isOSBinFormatELF()) {
+ if (Fn->hasComdat()) {
+ Section = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS,
+ ELF::SHF_ALLOC | ELF::SHF_GROUP, 0,
+ Fn->getComdat()->getName());
+ } else {
+ Section = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS,
+ ELF::SHF_ALLOC);
+ }
+ } else if (MF->getSubtarget().getTargetTriple().isOSBinFormatMachO()) {
+ Section = OutContext.getMachOSection("__DATA", "xray_instr_map", 0,
+ SectionKind::getReadOnlyWithRel());
+ } else {
+ llvm_unreachable("Unsupported target");
+ }
+
+ // Before we switch over, we force a reference to a label inside the
+ // xray_instr_map section. Since this function is always called just
+ // before the function's end, we assume that this is happening after
+ // the last return instruction.
+
+ auto WordSizeBytes = TM.getPointerSize();
+ MCSymbol *Tmp = OutContext.createTempSymbol("xray_synthetic_", true);
+ OutStreamer->EmitCodeAlignment(16);
+ OutStreamer->EmitSymbolValue(Tmp, WordSizeBytes, false);
+ OutStreamer->SwitchSection(Section);
+ OutStreamer->EmitLabel(Tmp);
+ for (const auto &Sled : Sleds)
+ Sled.emit(WordSizeBytes, OutStreamer.get(), CurrentFnSym);
+
+ OutStreamer->SwitchSection(PrevSection);
+ Sleds.clear();
+}
+
void AsmPrinter::recordSled(MCSymbol *Sled, const MachineInstr &MI,
SledKind Kind) {
auto Fn = MI.getParent()->getParent()->getFunction();
diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp
index 422f2dc2f2fb..3d81184f774a 100644
--- a/lib/CodeGen/InlineSpiller.cpp
+++ b/lib/CodeGen/InlineSpiller.cpp
@@ -1124,7 +1124,7 @@ void HoistSpillHelper::rmRedundantSpills(
// earlier spill with smaller SlotIndex.
for (const auto CurrentSpill : Spills) {
MachineBasicBlock *Block = CurrentSpill->getParent();
- MachineDomTreeNode *Node = MDT.DT->getNode(Block);
+ MachineDomTreeNode *Node = MDT.getBase().getNode(Block);
MachineInstr *PrevSpill = SpillBBToSpill[Node];
if (PrevSpill) {
SlotIndex PIdx = LIS.getInstructionIndex(*PrevSpill);
@@ -1132,9 +1132,9 @@ void HoistSpillHelper::rmRedundantSpills(
MachineInstr *SpillToRm = (CIdx > PIdx) ? CurrentSpill : PrevSpill;
MachineInstr *SpillToKeep = (CIdx > PIdx) ? PrevSpill : CurrentSpill;
SpillsToRm.push_back(SpillToRm);
- SpillBBToSpill[MDT.DT->getNode(Block)] = SpillToKeep;
+ SpillBBToSpill[MDT.getBase().getNode(Block)] = SpillToKeep;
} else {
- SpillBBToSpill[MDT.DT->getNode(Block)] = CurrentSpill;
+ SpillBBToSpill[MDT.getBase().getNode(Block)] = CurrentSpill;
}
}
for (const auto SpillToRm : SpillsToRm)
@@ -1209,7 +1209,7 @@ void HoistSpillHelper::getVisitOrders(
// Sort the nodes in WorkSet in top-down order and save the nodes
// in Orders. Orders will be used for hoisting in runHoistSpills.
unsigned idx = 0;
- Orders.push_back(MDT.DT->getNode(Root));
+ Orders.push_back(MDT.getBase().getNode(Root));
do {
MachineDomTreeNode *Node = Orders[idx++];
const std::vector<MachineDomTreeNode *> &Children = Node->getChildren();
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index b4b41c3d0011..4632484055d2 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -4277,7 +4277,8 @@ struct BaseIndexOffset {
}
/// Parses tree in Ptr for base, index, offset addresses.
- static BaseIndexOffset match(SDValue Ptr, SelectionDAG &DAG) {
+ static BaseIndexOffset match(SDValue Ptr, SelectionDAG &DAG,
+ int64_t PartialOffset = 0) {
bool IsIndexSignExt = false;
// Split up a folded GlobalAddress+Offset into its component parts.
@@ -4286,7 +4287,7 @@ struct BaseIndexOffset {
return BaseIndexOffset(DAG.getGlobalAddress(GA->getGlobal(),
SDLoc(GA),
GA->getValueType(0),
- /*Offset=*/0,
+ /*Offset=*/PartialOffset,
/*isTargetGA=*/false,
GA->getTargetFlags()),
SDValue(),
@@ -4298,14 +4299,13 @@ struct BaseIndexOffset {
// instruction, then it could be just the BASE or everything else we don't
// know how to handle. Just use Ptr as BASE and give up.
if (Ptr->getOpcode() != ISD::ADD)
- return BaseIndexOffset(Ptr, SDValue(), 0, IsIndexSignExt);
+ return BaseIndexOffset(Ptr, SDValue(), PartialOffset, IsIndexSignExt);
// We know that we have at least an ADD instruction. Try to pattern match
// the simple case of BASE + OFFSET.
if (isa<ConstantSDNode>(Ptr->getOperand(1))) {
int64_t Offset = cast<ConstantSDNode>(Ptr->getOperand(1))->getSExtValue();
- return BaseIndexOffset(Ptr->getOperand(0), SDValue(), Offset,
- IsIndexSignExt);
+ return match(Ptr->getOperand(0), DAG, Offset + PartialOffset);
}
// Inside a loop the current BASE pointer is calculated using an ADD and a
@@ -4314,7 +4314,7 @@ struct BaseIndexOffset {
// (i64 mul (i64 %induction_var)
// (i64 %element_size)))
if (Ptr->getOperand(1)->getOpcode() == ISD::MUL)
- return BaseIndexOffset(Ptr, SDValue(), 0, IsIndexSignExt);
+ return BaseIndexOffset(Ptr, SDValue(), PartialOffset, IsIndexSignExt);
// Look at Base + Index + Offset cases.
SDValue Base = Ptr->getOperand(0);
@@ -4328,14 +4328,14 @@ struct BaseIndexOffset {
// Either the case of Base + Index (no offset) or something else.
if (IndexOffset->getOpcode() != ISD::ADD)
- return BaseIndexOffset(Base, IndexOffset, 0, IsIndexSignExt);
+ return BaseIndexOffset(Base, IndexOffset, PartialOffset, IsIndexSignExt);
// Now we have the case of Base + Index + offset.
SDValue Index = IndexOffset->getOperand(0);
SDValue Offset = IndexOffset->getOperand(1);
if (!isa<ConstantSDNode>(Offset))
- return BaseIndexOffset(Ptr, SDValue(), 0, IsIndexSignExt);
+ return BaseIndexOffset(Ptr, SDValue(), PartialOffset, IsIndexSignExt);
// Ignore signextends.
if (Index->getOpcode() == ISD::SIGN_EXTEND) {
@@ -4344,7 +4344,7 @@ struct BaseIndexOffset {
} else IsIndexSignExt = false;
int64_t Off = cast<ConstantSDNode>(Offset)->getSExtValue();
- return BaseIndexOffset(Base, Index, Off, IsIndexSignExt);
+ return BaseIndexOffset(Base, Index, Off + PartialOffset, IsIndexSignExt);
}
};
} // namespace