brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · ea052e8 Raw
84 lines · cpp
1//===- OutputSegment.h -----------------------------------------*- C++ -*-===//2//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "OutputSegment.h"10#include "InputChunks.h"11#include "lld/Common/Memory.h"12 13#define DEBUG_TYPE "lld"14 15using namespace llvm;16using namespace llvm::wasm;17 18namespace lld::wasm {19 20void 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=" << name25                    << " size=" << inSeg->getSize()26                    << " align=" << inSeg->alignment << " at:" << size << "\n");27  inSeg->outputSeg = this;28  inSeg->outputSegmentOffset = size;29  size += inSeg->getSize();30}31 32// This function scans over the input segments.33//34// It removes MergeInputChunks from the input section array and adds35// new synthetic sections at the location of the first input section36// that it replaces. It then finalizes each synthetic section in order37// to compute an output offset for each piece of each input section.38void 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);44    if (!ms) {45      newSegments.push_back(s);46      continue;47    }48 49    // A segment should not make it here unless its alive50    assert(ms->live);51 52    auto i = llvm::find_if(mergedSegments, [=](SyntheticMergedChunk *seg) {53      return seg->flags == ms->flags && seg->alignment == ms->alignment;54    });55    if (i == mergedSegments.end()) {56      LLVM_DEBUG(llvm::dbgs() << "new merge segment: " << name57                              << " 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);63    } else {64      LLVM_DEBUG(llvm::dbgs() << "adding to merge segment: " << name << "\n");65    }66    (*i)->addMergeChunk(ms);67  }68 69  for (auto *ms : mergedSegments)70    ms->finalizeContents();71 72  inputSegments = newSegments;73  size = 0;74  for (InputChunk *seg : inputSegments) {75    size = llvm::alignTo(size, 1ULL << seg->alignment);76    LLVM_DEBUG(llvm::dbgs() << "outputSegmentOffset set: " << seg->name77                            << " -> " << size << "\n");78    seg->outputSegmentOffset = size;79    size += seg->getSize();80  }81}82 83} // namespace lld::wasm84