summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/MCELFStreamer.cpp
diff options
context:
space:
mode:
authorPeter Smith <peter.smith@linaro.org>2018-06-06 09:40:06 +0000
committerPeter Smith <peter.smith@linaro.org>2018-06-06 09:40:06 +0000
commit57f661bd7d20412f21ac6b7611c41a0f8b84fc01 (patch)
treea3c0558620a5a096f52d309b1d2e29fffc17c2a3 /llvm/lib/MC/MCELFStreamer.cpp
parentb7c374500607486d56ae16195b57ea737fa2e5a5 (diff)
downloadbcm5719-llvm-57f661bd7d20412f21ac6b7611c41a0f8b84fc01.tar.gz
bcm5719-llvm-57f661bd7d20412f21ac6b7611c41a0f8b84fc01.zip
[MC] Pass MCSubtargetInfo to fixupNeedsRelaxation and applyFixup
On targets like Arm some relaxations may only be performed when certain architectural features are available. As functions can be compiled with differing levels of architectural support we must make a judgement on whether we can relax based on the MCSubtargetInfo for the function. This change passes through the MCSubtargetInfo for the function to fixupNeedsRelaxation so that the decision on whether to relax can be made per function. In this patch, only the ARM backend makes use of this information. We must also pass the MCSubtargetInfo to applyFixup because some fixups skip error checking on the assumption that relaxation has occurred, to prevent code-generation errors applyFixup must see the same MCSubtargetInfo as fixupNeedsRelaxation. Differential Revision: https://reviews.llvm.org/D44928 llvm-svn: 334078
Diffstat (limited to 'llvm/lib/MC/MCELFStreamer.cpp')
-rw-r--r--llvm/lib/MC/MCELFStreamer.cpp30
1 files changed, 22 insertions, 8 deletions
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index b112bd9639d..df11495a954 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -83,7 +83,8 @@ void MCELFStreamer::mergeFragment(MCDataFragment *DF,
DF->getContents().size());
DF->getFixups().push_back(EF->getFixups()[i]);
}
- DF->setHasInstructions(true);
+ if (DF->getSubtargetInfo() == nullptr && EF->getSubtargetInfo())
+ DF->setHasInstructions(*EF->getSubtargetInfo());
DF->getContents().append(EF->getContents().begin(), EF->getContents().end());
}
@@ -493,6 +494,15 @@ void MCELFStreamer::EmitInstToFragment(const MCInst &Inst,
fixSymbolsInTLSFixups(F.getFixups()[i].getValue());
}
+// A fragment can only have one Subtarget, and when bundling is enabled we
+// sometimes need to use the same fragment. We give an error if there
+// are conflicting Subtargets.
+static void CheckBundleSubtargets(const MCSubtargetInfo *OldSTI,
+ const MCSubtargetInfo *NewSTI) {
+ if (OldSTI && NewSTI && OldSTI != NewSTI)
+ report_fatal_error("A Bundle can only have one Subtarget.");
+}
+
void MCELFStreamer::EmitInstToData(const MCInst &Inst,
const MCSubtargetInfo &STI) {
MCAssembler &Assembler = getAssembler();
@@ -508,7 +518,7 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst,
//
// If bundling is disabled, append the encoded instruction to the current data
// fragment (or create a new such fragment if the current fragment is not a
- // data fragment).
+ // data fragment, or the Subtarget has changed).
//
// If bundling is enabled:
// - If we're not in a bundle-locked group, emit the instruction into a
@@ -523,19 +533,23 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst,
if (Assembler.isBundlingEnabled()) {
MCSection &Sec = *getCurrentSectionOnly();
- if (Assembler.getRelaxAll() && isBundleLocked())
+ if (Assembler.getRelaxAll() && isBundleLocked()) {
// If the -mc-relax-all flag is used and we are bundle-locked, we re-use
// the current bundle group.
DF = BundleGroups.back();
+ CheckBundleSubtargets(DF->getSubtargetInfo(), &STI);
+ }
else if (Assembler.getRelaxAll() && !isBundleLocked())
// When not in a bundle-locked group and the -mc-relax-all flag is used,
// we create a new temporary fragment which will be later merged into
// the current fragment.
DF = new MCDataFragment();
- else if (isBundleLocked() && !Sec.isBundleGroupBeforeFirstInst())
+ else if (isBundleLocked() && !Sec.isBundleGroupBeforeFirstInst()) {
// If we are bundle-locked, we re-use the current fragment.
// The bundle-locking directive ensures this is a new data fragment.
DF = cast<MCDataFragment>(getCurrentFragment());
+ CheckBundleSubtargets(DF->getSubtargetInfo(), &STI);
+ }
else if (!isBundleLocked() && Fixups.size() == 0) {
// Optimize memory usage by emitting the instruction to a
// MCCompactEncodedInstFragment when not in a bundle-locked group and
@@ -560,7 +574,7 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst,
// to be turned off.
Sec.setBundleGroupBeforeFirstInst(false);
} else {
- DF = getOrCreateDataFragment();
+ DF = getOrCreateDataFragment(&STI);
}
// Add the fixups and data.
@@ -568,12 +582,12 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst,
Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
DF->getFixups().push_back(Fixups[i]);
}
- DF->setHasInstructions(true);
+ DF->setHasInstructions(STI);
DF->getContents().append(Code.begin(), Code.end());
if (Assembler.isBundlingEnabled() && Assembler.getRelaxAll()) {
if (!isBundleLocked()) {
- mergeFragment(getOrCreateDataFragment(), DF);
+ mergeFragment(getOrCreateDataFragment(&STI), DF);
delete DF;
}
}
@@ -633,7 +647,7 @@ void MCELFStreamer::EmitBundleUnlock() {
// FIXME: Use more separate fragments for nested groups.
if (!isBundleLocked()) {
- mergeFragment(getOrCreateDataFragment(), DF);
+ mergeFragment(getOrCreateDataFragment(DF->getSubtargetInfo()), DF);
BundleGroups.pop_back();
delete DF;
}
OpenPOWER on IntegriCloud