summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/MCAssembler.cpp
diff options
context:
space:
mode:
authorPetr Hosek <phosek@chromium.org>2015-06-27 01:49:53 +0000
committerPetr Hosek <phosek@chromium.org>2015-06-27 01:49:53 +0000
commit4bbf563f6eaba4eb101ee76893a562a89b04a9ec (patch)
tree6fd8f19fc3d3bee99f1c3ada5aa7615dbfe51c6c /llvm/lib/MC/MCAssembler.cpp
parent203cbe7f6f53c5e95ebf4f870bb9dae53a0a5c72 (diff)
downloadbcm5719-llvm-4bbf563f6eaba4eb101ee76893a562a89b04a9ec.tar.gz
bcm5719-llvm-4bbf563f6eaba4eb101ee76893a562a89b04a9ec.zip
[MC] Align fragments when -mc-relax-all flag is used
Summary: Ensure that fragments are bundle aligned when instruction bundling is enabled and the -mc-relax-all flag is set. This is implicitly assumed by the bundle padding implementation but this assumption does not hold when custom alignment is being used. The change was tested by running PNaCl toolchain trybots with -mc-relax-all flag set. Fixes https://code.google.com/p/nativeclient/issues/detail?id=4063 Test Plan: Regression test attached Reviewers: mseaborn Subscribers: jfb, llvm-commits Differential Revision: http://reviews.llvm.org/D10044 llvm-svn: 240869
Diffstat (limited to 'llvm/lib/MC/MCAssembler.cpp')
-rw-r--r--llvm/lib/MC/MCAssembler.cpp18
1 files changed, 12 insertions, 6 deletions
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index 76be67cafc5..da6516a4ac9 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -254,7 +254,7 @@ uint64_t llvm::computeBundlePadding(const MCAssembler &Assembler,
else { // EndOfFragment > BundleSize
return 2 * BundleSize - EndOfFragment;
}
- } else if (EndOfFragment > BundleSize)
+ } else if (OffsetInBundle > 0 && EndOfFragment > BundleSize)
return BundleSize - OffsetInBundle;
else
return 0;
@@ -581,16 +581,22 @@ void MCAsmLayout::layoutFragment(MCFragment *F) {
// size won't include the padding.
//
// When the -mc-relax-all flag is used, we optimize bundling by writting the
- // bundle padding directly into fragments when the instructions are emitted
- // inside the streamer.
+ // padding directly into fragments when the instructions are emitted inside
+ // the streamer. When the fragment is larger than the bundle size, we need to
+ // ensure that it's bundle aligned. This means that if we end up with
+ // multiple fragments, we must emit bundle padding between fragments.
//
- if (Assembler.isBundlingEnabled() && !Assembler.getRelaxAll() &&
- F->hasInstructions()) {
+ // ".align N" is an example of a directive that introduces multiple
+ // fragments. We could add a special case to handle ".align N" by emitting
+ // within-fragment padding (which would produce less padding when N is less
+ // than the bundle size), but for now we don't.
+ //
+ if (Assembler.isBundlingEnabled() && F->hasInstructions()) {
assert(isa<MCEncodedFragment>(F) &&
"Only MCEncodedFragment implementations have instructions");
uint64_t FSize = Assembler.computeFragmentSize(*this, *F);
- if (FSize > Assembler.getBundleAlignSize())
+ if (!Assembler.getRelaxAll() && FSize > Assembler.getBundleAlignSize())
report_fatal_error("Fragment can't be larger than a bundle size");
uint64_t RequiredBundlePadding = computeBundlePadding(Assembler, F,
OpenPOWER on IntegriCloud