Pull in r322131 from upstream llvm trunk (by Rafael Espíndola):

Use a MCExpr for the size of MCFillFragment.

  This allows the size to be found during ralaxation. This fixes
  [LLVM] pr35858.

Requested by:	royger
This commit is contained in:
Ed Maste 2018-01-30 16:43:20 +00:00
parent 88e56272f9
commit e5c2ece714
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=328596
4 changed files with 29 additions and 20 deletions

View File

@ -422,14 +422,21 @@ class MCFillFragment : public MCFragment {
uint8_t Value;
/// The number of bytes to insert.
uint64_t Size;
const MCExpr &Size;
/// Source location of the directive that this fragment was created for.
SMLoc Loc;
public:
MCFillFragment(uint8_t Value, uint64_t Size, MCSection *Sec = nullptr)
: MCFragment(FT_Fill, false, 0, Sec), Value(Value), Size(Size) {}
MCFillFragment(uint8_t Value, const MCExpr &Size, SMLoc Loc,
MCSection *Sec = nullptr)
: MCFragment(FT_Fill, false, 0, Sec), Value(Value), Size(Size), Loc(Loc) {
}
uint8_t getValue() const { return Value; }
uint64_t getSize() const { return Size; }
const MCExpr &getSize() const { return Size; }
SMLoc getLoc() const { return Loc; }
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Fill;

View File

@ -281,8 +281,18 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
return cast<MCRelaxableFragment>(F).getContents().size();
case MCFragment::FT_CompactEncodedInst:
return cast<MCCompactEncodedInstFragment>(F).getContents().size();
case MCFragment::FT_Fill:
return cast<MCFillFragment>(F).getSize();
case MCFragment::FT_Fill: {
auto &FF = cast<MCFillFragment>(F);
int64_t Size = 0;
if (!FF.getSize().evaluateAsAbsolute(Size, Layout))
getContext().reportError(FF.getLoc(),
"expected assembly-time absolute expression");
if (Size < 0) {
getContext().reportError(FF.getLoc(), "invalid number of bytes");
return 0;
}
return Size;
}
case MCFragment::FT_LEB:
return cast<MCLEBFragment>(F).getContents().size();
@ -540,7 +550,7 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
for (unsigned I = 1; I < MaxChunkSize; ++I)
Data[I] = Data[0];
uint64_t Size = FF.getSize();
uint64_t Size = FragmentSize;
for (unsigned ChunkSize = MaxChunkSize; ChunkSize; ChunkSize /= 2) {
StringRef Ref(Data, ChunkSize);
for (uint64_t I = 0, E = Size / ChunkSize; I != E; ++I)

View File

@ -582,19 +582,8 @@ void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
MCDataFragment *DF = getOrCreateDataFragment();
flushPendingLabels(DF, DF->getContents().size());
int64_t IntNumBytes;
if (!NumBytes.evaluateAsAbsolute(IntNumBytes, getAssembler())) {
getContext().reportError(Loc, "expected absolute expression");
return;
}
if (IntNumBytes < 0) {
getContext().reportError(Loc, "invalid number of bytes");
return;
}
assert(getCurrentSectionOnly() && "need a section");
insert(new MCFillFragment(FillValue, IntNumBytes));
insert(new MCFillFragment(FillValue, NumBytes, Loc));
}
void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,

View File

@ -528,7 +528,10 @@ static void addData(SmallVectorImpl<char> &DataBytes,
Align->getMaxBytesToEmit());
DataBytes.resize(Size, Value);
} else if (auto *Fill = dyn_cast<MCFillFragment>(&Frag)) {
DataBytes.insert(DataBytes.end(), Fill->getSize(), Fill->getValue());
int64_t Size;
if (!Fill->getSize().evaluateAsAbsolute(Size))
llvm_unreachable("The fill should be an assembler constant");
DataBytes.insert(DataBytes.end(), Size, Fill->getValue());
} else {
const auto &DataFrag = cast<MCDataFragment>(Frag);
const SmallVectorImpl<char> &Contents = DataFrag.getContents();