16bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//===---- CGLoopInfo.cpp - LLVM CodeGen for loop metadata -*- C++ -*-------===// 26bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// 36bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// The LLVM Compiler Infrastructure 46bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// 56bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// This file is distributed under the University of Illinois Open Source 66bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// License. See LICENSE.TXT for details. 76bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// 86bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//===----------------------------------------------------------------------===// 96bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "CGLoopInfo.h" 116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/IR/BasicBlock.h" 126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/IR/Constants.h" 136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/IR/InstrTypes.h" 146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/IR/Instructions.h" 156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/IR/Metadata.h" 166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesusing namespace clang; 176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesusing namespace CodeGen; 186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesusing namespace llvm; 196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesstatic MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs) { 216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Attrs.IsParallel && Attrs.VectorizerWidth == 0 && 236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Attrs.VectorizerUnroll == 0 && 246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Attrs.VectorizerEnable == LoopAttributes::VecUnspecified) 256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SmallVector<Value *, 4> Args; 286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Reserve operand 0 for loop id self reference. 296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines MDNode *TempNode = MDNode::getTemporary(Ctx, None); 306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Args.push_back(TempNode); 316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Setting vectorizer.width 336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Attrs.VectorizerWidth > 0) { 34ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Value *Vals[] = { MDString::get(Ctx, "llvm.loop.vectorize.width"), 356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ConstantInt::get(Type::getInt32Ty(Ctx), 366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Attrs.VectorizerWidth) }; 376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Args.push_back(MDNode::get(Ctx, Vals)); 386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Setting vectorizer.unroll 416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Attrs.VectorizerUnroll > 0) { 42ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Value *Vals[] = { MDString::get(Ctx, "llvm.loop.vectorize.unroll"), 436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ConstantInt::get(Type::getInt32Ty(Ctx), 446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Attrs.VectorizerUnroll) }; 456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Args.push_back(MDNode::get(Ctx, Vals)); 466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Setting vectorizer.enable 496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Attrs.VectorizerEnable != LoopAttributes::VecUnspecified) { 50ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Value *Vals[] = { MDString::get(Ctx, "llvm.loop.vectorize.enable"), 516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ConstantInt::get(Type::getInt1Ty(Ctx), 526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines (Attrs.VectorizerEnable == 536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LoopAttributes::VecEnable)) }; 546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Args.push_back(MDNode::get(Ctx, Vals)); 556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines MDNode *LoopID = MDNode::get(Ctx, Args); 586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(LoopID->use_empty() && "LoopID should not be used"); 596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Set the first operand to itself. 616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LoopID->replaceOperandWith(0, LoopID); 626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines MDNode::deleteTemporary(TempNode); 636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return LoopID; 646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesLoopAttributes::LoopAttributes(bool IsParallel) 676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines : IsParallel(IsParallel), VectorizerEnable(LoopAttributes::VecUnspecified), 686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines VectorizerWidth(0), VectorizerUnroll(0) {} 696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid LoopAttributes::clear() { 716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines IsParallel = false; 726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines VectorizerWidth = 0; 736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines VectorizerUnroll = 0; 746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines VectorizerEnable = LoopAttributes::VecUnspecified; 756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesLoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs) 786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines : LoopID(nullptr), Header(Header), Attrs(Attrs) { 796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LoopID = createMetadata(Header->getContext(), Attrs); 806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid LoopInfoStack::push(BasicBlock *Header) { 836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Active.push_back(LoopInfo(Header, StagedAttrs)); 846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Clear the attributes so nested loops do not inherit them. 856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines StagedAttrs.clear(); 866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid LoopInfoStack::pop() { 896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(!Active.empty() && "No active loops to pop"); 906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Active.pop_back(); 916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid LoopInfoStack::InsertHelper(Instruction *I) const { 946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!hasInfo()) 956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const LoopInfo &L = getInfo(); 986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!L.getLoopID()) 996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 1006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I)) { 1026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (unsigned i = 0, ie = TI->getNumSuccessors(); i < ie; ++i) 1036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (TI->getSuccessor(i) == L.getHeader()) { 1046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TI->setMetadata("llvm.loop", L.getLoopID()); 1056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines break; 1066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 1076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 1086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 1096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (L.getAttributes().IsParallel && I->mayReadOrWriteMemory()) 1116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines I->setMetadata("llvm.mem.parallel_loop_access", L.getLoopID()); 1126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 113