BranchIslandFactory.cpp revision 37b74a387bb3993387029859c2d9d051c41c724e
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 11#include "mcld/Fragment/Fragment.h" 12#include "mcld/LD/LDSection.h" 13#include "mcld/LD/SectionData.h" 14#include "mcld/Module.h" 15 16namespace mcld { 17 18//===----------------------------------------------------------------------===// 19// BranchIslandFactory 20//===----------------------------------------------------------------------===// 21 22/// ctor 23/// @param pMaxFwdBranchRange - the max forward branch range of the target 24/// @param pMaxBwdBranchRange - the max backward branch range of the target 25/// @param pMaxIslandSize - the predefined value for the max size of a island 26BranchIslandFactory::BranchIslandFactory(int64_t pMaxFwdBranchRange, 27 int64_t pMaxBwdBranchRange, 28 size_t pMaxIslandSize) 29 : GCFactory<BranchIsland, 0>(1u), // magic number 30 m_MaxFwdBranchRange(pMaxFwdBranchRange - pMaxIslandSize), 31 m_MaxBwdBranchRange(pMaxBwdBranchRange + pMaxIslandSize), 32 m_MaxIslandSize(pMaxIslandSize) { 33} 34 35BranchIslandFactory::~BranchIslandFactory() { 36} 37 38/// group - group fragments and create islands when needed 39/// @param pSectionData - the SectionData holds fragments need to be grouped 40void BranchIslandFactory::group(Module& pModule) { 41 /* FIXME: 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_MaxFwdBranchRange; 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_MaxFwdBranchRange; 55 } 56 } 57 } 58 if (getIslands(sd.back()).first == 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 BranchIsland* island = allocate(); 67 new (island) BranchIsland(pFragment, // entry fragment to the island 68 m_MaxIslandSize, // the max size of the island 69 size() - 1u); // index in the island factory 70 return island; 71} 72 73/// getIsland - find fwd and bwd islands for the fragment 74/// @param pFragment - the fragment needs a branch island 75std::pair<BranchIsland*, BranchIsland*> BranchIslandFactory::getIslands( 76 const Fragment& pFragment) { 77 BranchIsland* fwd = NULL; 78 BranchIsland* bwd = NULL; 79 for (iterator it = begin(), ie = end(), prev = ie; it != ie; 80 prev = it, ++it) { 81 if ((pFragment.getOffset() < (*it).offset()) && 82 ((pFragment.getOffset() + m_MaxFwdBranchRange) >= (*it).offset())) { 83 fwd = &*it; 84 85 if (prev != ie) { 86 int64_t bwd_off = (int64_t)pFragment.getOffset() + m_MaxBwdBranchRange; 87 if ((pFragment.getOffset() > (*prev).offset()) && 88 (bwd_off <= (int64_t)(*prev).offset())) { 89 bwd = &*prev; 90 } 91 } 92 break; 93 } 94 } 95 return std::make_pair(fwd, bwd); 96} 97 98} // namespace mcld 99