forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			111 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C++
		
	
	
	
//===---- CGLoopInfo.cpp - LLVM CodeGen for loop metadata -*- C++ -*-------===//
 | 
						|
//
 | 
						|
//                     The LLVM Compiler Infrastructure
 | 
						|
//
 | 
						|
// This file is distributed under the University of Illinois Open Source
 | 
						|
// License. See LICENSE.TXT for details.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#include "CGLoopInfo.h"
 | 
						|
#include "llvm/IR/BasicBlock.h"
 | 
						|
#include "llvm/IR/Constants.h"
 | 
						|
#include "llvm/IR/InstrTypes.h"
 | 
						|
#include "llvm/IR/Instructions.h"
 | 
						|
#include "llvm/IR/Metadata.h"
 | 
						|
using namespace clang;
 | 
						|
using namespace CodeGen;
 | 
						|
using namespace llvm;
 | 
						|
 | 
						|
static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs) {
 | 
						|
 | 
						|
  if (!Attrs.IsParallel && Attrs.VectorizerWidth == 0 &&
 | 
						|
      Attrs.VectorizerUnroll == 0 &&
 | 
						|
      Attrs.VectorizerEnable == LoopAttributes::VecUnspecified)
 | 
						|
    return nullptr;
 | 
						|
 | 
						|
  SmallVector<Metadata *, 4> Args;
 | 
						|
  // Reserve operand 0 for loop id self reference.
 | 
						|
  auto TempNode = MDNode::getTemporary(Ctx, None);
 | 
						|
  Args.push_back(TempNode.get());
 | 
						|
 | 
						|
  // Setting vectorizer.width
 | 
						|
  if (Attrs.VectorizerWidth > 0) {
 | 
						|
    Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.width"),
 | 
						|
                        ConstantAsMetadata::get(ConstantInt::get(
 | 
						|
                            Type::getInt32Ty(Ctx), Attrs.VectorizerWidth))};
 | 
						|
    Args.push_back(MDNode::get(Ctx, Vals));
 | 
						|
  }
 | 
						|
 | 
						|
  // Setting vectorizer.unroll
 | 
						|
  if (Attrs.VectorizerUnroll > 0) {
 | 
						|
    Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.interleave.count"),
 | 
						|
                        ConstantAsMetadata::get(ConstantInt::get(
 | 
						|
                            Type::getInt32Ty(Ctx), Attrs.VectorizerUnroll))};
 | 
						|
    Args.push_back(MDNode::get(Ctx, Vals));
 | 
						|
  }
 | 
						|
 | 
						|
  // Setting vectorizer.enable
 | 
						|
  if (Attrs.VectorizerEnable != LoopAttributes::VecUnspecified) {
 | 
						|
    Metadata *Vals[] = {
 | 
						|
        MDString::get(Ctx, "llvm.loop.vectorize.enable"),
 | 
						|
        ConstantAsMetadata::get(ConstantInt::get(
 | 
						|
            Type::getInt1Ty(Ctx),
 | 
						|
            (Attrs.VectorizerEnable == LoopAttributes::VecEnable)))};
 | 
						|
    Args.push_back(MDNode::get(Ctx, Vals));
 | 
						|
  }
 | 
						|
 | 
						|
  // Set the first operand to itself.
 | 
						|
  MDNode *LoopID = MDNode::get(Ctx, Args);
 | 
						|
  LoopID->replaceOperandWith(0, LoopID);
 | 
						|
  return LoopID;
 | 
						|
}
 | 
						|
 | 
						|
LoopAttributes::LoopAttributes(bool IsParallel)
 | 
						|
    : IsParallel(IsParallel), VectorizerEnable(LoopAttributes::VecUnspecified),
 | 
						|
      VectorizerWidth(0), VectorizerUnroll(0) {}
 | 
						|
 | 
						|
void LoopAttributes::clear() {
 | 
						|
  IsParallel = false;
 | 
						|
  VectorizerWidth = 0;
 | 
						|
  VectorizerUnroll = 0;
 | 
						|
  VectorizerEnable = LoopAttributes::VecUnspecified;
 | 
						|
}
 | 
						|
 | 
						|
LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs)
 | 
						|
    : LoopID(nullptr), Header(Header), Attrs(Attrs) {
 | 
						|
  LoopID = createMetadata(Header->getContext(), Attrs);
 | 
						|
}
 | 
						|
 | 
						|
void LoopInfoStack::push(BasicBlock *Header) {
 | 
						|
  Active.push_back(LoopInfo(Header, StagedAttrs));
 | 
						|
  // Clear the attributes so nested loops do not inherit them.
 | 
						|
  StagedAttrs.clear();
 | 
						|
}
 | 
						|
 | 
						|
void LoopInfoStack::pop() {
 | 
						|
  assert(!Active.empty() && "No active loops to pop");
 | 
						|
  Active.pop_back();
 | 
						|
}
 | 
						|
 | 
						|
void LoopInfoStack::InsertHelper(Instruction *I) const {
 | 
						|
  if (!hasInfo())
 | 
						|
    return;
 | 
						|
 | 
						|
  const LoopInfo &L = getInfo();
 | 
						|
  if (!L.getLoopID())
 | 
						|
    return;
 | 
						|
 | 
						|
  if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I)) {
 | 
						|
    for (unsigned i = 0, ie = TI->getNumSuccessors(); i < ie; ++i)
 | 
						|
      if (TI->getSuccessor(i) == L.getHeader()) {
 | 
						|
        TI->setMetadata("llvm.loop", L.getLoopID());
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  if (L.getAttributes().IsParallel && I->mayReadOrWriteMemory())
 | 
						|
    I->setMetadata("llvm.mem.parallel_loop_access", L.getLoopID());
 | 
						|
}
 |