10b57cec5SDimitry Andric //===-- LiveRangeUtils.h - Live Range modification utilities ----*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric /// \file 90b57cec5SDimitry Andric /// This file contains helper functions to modify live ranges. 10fe6060f1SDimitry Andric /// 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_LIB_CODEGEN_LIVERANGEUTILS_H 140b57cec5SDimitry Andric #define LLVM_LIB_CODEGEN_LIVERANGEUTILS_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "llvm/CodeGen/LiveInterval.h" 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric namespace llvm { 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric /// Helper function that distributes live range value numbers and the 21*4824e7fdSDimitry Andric /// corresponding segments of a primary live range \p LR to a list of newly 220b57cec5SDimitry Andric /// created live ranges \p SplitLRs. \p VNIClasses maps each value number in \p 230b57cec5SDimitry Andric /// LR to 0 meaning it should stay or to 1..N meaning it should go to a specific 240b57cec5SDimitry Andric /// live range in the \p SplitLRs array. 250b57cec5SDimitry Andric template<typename LiveRangeT, typename EqClassesT> DistributeRange(LiveRangeT & LR,LiveRangeT * SplitLRs[],EqClassesT VNIClasses)260b57cec5SDimitry Andricstatic void DistributeRange(LiveRangeT &LR, LiveRangeT *SplitLRs[], 270b57cec5SDimitry Andric EqClassesT VNIClasses) { 280b57cec5SDimitry Andric // Move segments to new intervals. 290b57cec5SDimitry Andric typename LiveRangeT::iterator J = LR.begin(), E = LR.end(); 300b57cec5SDimitry Andric while (J != E && VNIClasses[J->valno->id] == 0) 310b57cec5SDimitry Andric ++J; 320b57cec5SDimitry Andric for (typename LiveRangeT::iterator I = J; I != E; ++I) { 330b57cec5SDimitry Andric if (unsigned eq = VNIClasses[I->valno->id]) { 340b57cec5SDimitry Andric assert((SplitLRs[eq-1]->empty() || SplitLRs[eq-1]->expiredAt(I->start)) && 350b57cec5SDimitry Andric "New intervals should be empty"); 360b57cec5SDimitry Andric SplitLRs[eq-1]->segments.push_back(*I); 370b57cec5SDimitry Andric } else 380b57cec5SDimitry Andric *J++ = *I; 390b57cec5SDimitry Andric } 400b57cec5SDimitry Andric LR.segments.erase(J, E); 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric // Transfer VNInfos to their new owners and renumber them. 430b57cec5SDimitry Andric unsigned j = 0, e = LR.getNumValNums(); 440b57cec5SDimitry Andric while (j != e && VNIClasses[j] == 0) 450b57cec5SDimitry Andric ++j; 460b57cec5SDimitry Andric for (unsigned i = j; i != e; ++i) { 470b57cec5SDimitry Andric VNInfo *VNI = LR.getValNumInfo(i); 480b57cec5SDimitry Andric if (unsigned eq = VNIClasses[i]) { 490b57cec5SDimitry Andric VNI->id = SplitLRs[eq-1]->getNumValNums(); 500b57cec5SDimitry Andric SplitLRs[eq-1]->valnos.push_back(VNI); 510b57cec5SDimitry Andric } else { 520b57cec5SDimitry Andric VNI->id = j; 530b57cec5SDimitry Andric LR.valnos[j++] = VNI; 540b57cec5SDimitry Andric } 550b57cec5SDimitry Andric } 560b57cec5SDimitry Andric LR.valnos.resize(j); 570b57cec5SDimitry Andric } 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric } // End llvm namespace 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric #endif 62