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
;
20 void OutputSegment::addInputSegment(InputChunk
*inSeg
) {
21 alignment
= std::max(alignment
, inSeg
->alignment
);
22 inputSegments
.push_back(inSeg
);
23 size
= llvm::alignTo(size
, 1ULL << inSeg
->alignment
);
24 LLVM_DEBUG(dbgs() << "addInputSegment: " << inSeg
->name
<< " oname=" << name
25 << " size=" << inSeg
->getSize()
26 << " align=" << inSeg
->alignment
<< " at:" << size
<< "\n");
27 inSeg
->outputSeg
= this;
28 inSeg
->outputSegmentOffset
= size
;
29 size
+= inSeg
->getSize();
32 // This function scans over the input segments.
34 // It removes MergeInputChunks from the input section array and adds
35 // new synthetic sections at the location of the first input section
36 // that it replaces. It then finalizes each synthetic section in order
37 // to compute an output offset for each piece of each input section.
38 void OutputSegment::finalizeInputSegments() {
39 LLVM_DEBUG(llvm::dbgs() << "finalizeInputSegments: " << name
<< "\n");
40 std::vector
<SyntheticMergedChunk
*> mergedSegments
;
41 std::vector
<InputChunk
*> newSegments
;
42 for (InputChunk
*s
: inputSegments
) {
43 MergeInputChunk
*ms
= dyn_cast
<MergeInputChunk
>(s
);
45 newSegments
.push_back(s
);
49 // A segment should not make it here unless its alive
52 auto i
= llvm::find_if(mergedSegments
, [=](SyntheticMergedChunk
*seg
) {
53 return seg
->flags
== ms
->flags
&& seg
->alignment
== ms
->alignment
;
55 if (i
== mergedSegments
.end()) {
56 LLVM_DEBUG(llvm::dbgs() << "new merge segment: " << name
57 << " alignment=" << ms
->alignment
<< "\n");
58 auto *syn
= make
<SyntheticMergedChunk
>(name
, ms
->alignment
, ms
->flags
);
59 syn
->outputSeg
= this;
60 mergedSegments
.push_back(syn
);
61 i
= std::prev(mergedSegments
.end());
62 newSegments
.push_back(syn
);
64 LLVM_DEBUG(llvm::dbgs() << "adding to merge segment: " << name
<< "\n");
66 (*i
)->addMergeChunk(ms
);
69 for (auto *ms
: mergedSegments
)
70 ms
->finalizeContents();
72 inputSegments
= newSegments
;
74 for (InputChunk
*seg
: inputSegments
) {
75 size
= llvm::alignTo(size
, 1ULL << seg
->alignment
);
76 LLVM_DEBUG(llvm::dbgs() << "outputSegmentOffset set: " << seg
->name
77 << " -> " << size
<< "\n");
78 seg
->outputSegmentOffset
= size
;
79 size
+= seg
->getSize();
83 } // namespace lld::wasm