BranchIslandFactory.cpp revision f33f6de54db174aa679a4b6d1e040d37e95541c0
1//===- BranchIslandFactory.cpp --------------------------------------------===// 2// 3// The MCLinker Project 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9#include <mcld/LD/BranchIslandFactory.h> 10#include <mcld/Fragment/Fragment.h> 11#include <mcld/LD/LDSection.h> 12#include <mcld/LD/SectionData.h> 13#include <mcld/Module.h> 14 15using namespace mcld; 16 17//===----------------------------------------------------------------------===// 18// BranchIslandFactory 19//===----------------------------------------------------------------------===// 20 21/// ctor 22/// @param pMaxBranchRange - the max branch range of the target backend 23/// @param pMaxIslandSize - a predifned value (1KB here) to decide the max 24/// size of the island 25BranchIslandFactory::BranchIslandFactory(uint64_t pMaxBranchRange, 26 uint64_t pMaxIslandSize) 27 : GCFactory<BranchIsland, 0>(1u), // magic number 28 m_MaxBranchRange(pMaxBranchRange - pMaxIslandSize), 29 m_MaxIslandSize(pMaxIslandSize) 30{ 31} 32 33BranchIslandFactory::~BranchIslandFactory() 34{ 35} 36 37/// group - group fragments and create islands when needed 38/// @param pSectionData - the SectionData holds fragments need to be grouped 39void BranchIslandFactory::group(Module& pModule) 40{ 41 /* Currently only support relaxing .text section! */ 42 LDSection* text = pModule.getSection(".text"); 43 if (text != NULL && text->hasSectionData()) { 44 SectionData& sd = *text->getSectionData(); 45 uint64_t group_end = m_MaxBranchRange - m_MaxIslandSize; 46 for (SectionData::iterator it = sd.begin(), ie = sd.end(); it != ie; ++it) { 47 if ((*it).getOffset() + (*it).size() > group_end) { 48 Fragment* frag = (*it).getPrevNode(); 49 while (frag != NULL && frag->getKind() == Fragment::Alignment) { 50 frag = frag->getPrevNode(); 51 } 52 if (frag != NULL) { 53 produce(*frag); 54 group_end = (*it).getOffset() + m_MaxBranchRange - m_MaxIslandSize; 55 } 56 } 57 } 58 if (find(sd.back()) == NULL) 59 produce(sd.back()); 60 } 61} 62 63/// produce - produce a island for the given fragment 64/// @param pFragment - the fragment needs a branch island 65BranchIsland* BranchIslandFactory::produce(Fragment& pFragment) 66{ 67 BranchIsland *island = allocate(); 68 new (island) BranchIsland(pFragment, // entry fragment to the island 69 m_MaxIslandSize, // the max size of the island 70 size() - 1u); // index in the island factory 71 return island; 72} 73 74/// find - find a island for the given fragment 75/// @param pFragment - the fragment needs a branch isladn 76BranchIsland* BranchIslandFactory::find(const Fragment& pFragment) 77{ 78 // Currently we always find the island in a forward direction. 79 // TODO: If we can search backward, then we may reduce the number of stubs. 80 for (iterator it = begin(), ie = end(); it != ie; ++it) { 81 if ((pFragment.getOffset() < (*it).offset()) && 82 ((pFragment.getOffset() + m_MaxBranchRange) >= (*it).offset())) 83 return &(*it); 84 } 85 return NULL; 86} 87 88