1 //===- OutputSegment.h -----------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "OutputSegment.h"
10 #include "InputChunks.h"
11 #include "lld/Common/Memory.h"
13 #define DEBUG_TYPE "lld"
16 using namespace llvm::wasm
;
22 void OutputSegment::addInputSegment(InputChunk
*inSeg
) {
23 alignment
= std::max(alignment
, inSeg
->alignment
);
24 inputSegments
.push_back(inSeg
);
25 size
= llvm::alignTo(size
, 1ULL << inSeg
->alignment
);
26 LLVM_DEBUG(dbgs() << "addInputSegment: " << inSeg
->getName()
27 << " oname=" << name
<< " size=" << inSeg
->getSize()
28 << " align=" << inSeg
->alignment
<< " at:" << size
<< "\n");
29 inSeg
->outputSeg
= this;
30 inSeg
->outputSegmentOffset
= size
;
31 size
+= inSeg
->getSize();
34 // This function scans over the input segments.
36 // It removes MergeInputChunks from the input section array and adds
37 // new synthetic sections at the location of the first input section
38 // that it replaces. It then finalizes each synthetic section in order
39 // to compute an output offset for each piece of each input section.
40 void OutputSegment::finalizeInputSegments() {
41 LLVM_DEBUG(llvm::dbgs() << "finalizeInputSegments: " << name
<< "\n");
42 std::vector
<SyntheticMergedChunk
*> mergedSegments
;
43 std::vector
<InputChunk
*> newSegments
;
44 for (InputChunk
*s
: inputSegments
) {
45 MergeInputChunk
*ms
= dyn_cast
<MergeInputChunk
>(s
);
47 newSegments
.push_back(s
);
51 // A segment should not make it here unless its alive
54 auto i
= llvm::find_if(mergedSegments
, [=](SyntheticMergedChunk
*seg
) {
55 return seg
->flags
== ms
->flags
&& seg
->alignment
== ms
->alignment
;
57 if (i
== mergedSegments
.end()) {
58 LLVM_DEBUG(llvm::dbgs() << "new merge segment: " << name
59 << " alignment=" << ms
->alignment
<< "\n");
60 auto *syn
= make
<SyntheticMergedChunk
>(name
, ms
->alignment
, ms
->flags
);
61 syn
->outputSeg
= this;
62 mergedSegments
.push_back(syn
);
63 i
= std::prev(mergedSegments
.end());
64 newSegments
.push_back(syn
);
66 LLVM_DEBUG(llvm::dbgs() << "adding to merge segment: " << name
<< "\n");
68 (*i
)->addMergeChunk(ms
);
71 for (auto *ms
: mergedSegments
)
72 ms
->finalizeContents();
74 inputSegments
= newSegments
;
76 for (InputChunk
*seg
: inputSegments
) {
77 size
= llvm::alignTo(size
, 1ULL << seg
->alignment
);
78 LLVM_DEBUG(llvm::dbgs() << "outputSegmentOffset set: " << seg
->getName()
79 << " -> " << size
<< "\n");
80 seg
->outputSegmentOffset
= size
;
81 size
+= seg
->getSize();