1f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===-- WebAssemblyOptimizeReturned.cpp - Optimize "returned" attributes --===// 2f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// 3f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// The LLVM Compiler Infrastructure 4f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// 5f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source 6f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// License. See LICENSE.TXT for details. 7f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// 8f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===----------------------------------------------------------------------===// 9f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// 10f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// \file 11f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// \brief Optimize calls with "returned" attributes for WebAssembly. 12f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// 13f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===----------------------------------------------------------------------===// 14f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 15f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "WebAssembly.h" 16f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/IR/Dominators.h" 17f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/IR/InstVisitor.h" 18f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Support/Debug.h" 19f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Support/raw_ostream.h" 20f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarusing namespace llvm; 21f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 22f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#define DEBUG_TYPE "wasm-optimize-returned" 23f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 24f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace { 25f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarclass OptimizeReturned final : public FunctionPass, 26f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar public InstVisitor<OptimizeReturned> { 27f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const char *getPassName() const override { 28f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return "WebAssembly Optimize Returned"; 29f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 30f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 31f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void getAnalysisUsage(AnalysisUsage &AU) const override { 32f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar AU.setPreservesCFG(); 33f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar AU.addRequired<DominatorTreeWrapperPass>(); 34f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar AU.addPreserved<DominatorTreeWrapperPass>(); 35f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FunctionPass::getAnalysisUsage(AU); 36f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 37f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 38f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool runOnFunction(Function &F) override; 39f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 40f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DominatorTree *DT; 41f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 42f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarpublic: 43f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar static char ID; 44f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar OptimizeReturned() : FunctionPass(ID), DT(nullptr) {} 45f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 46f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void visitCallSite(CallSite CS); 47f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}; 48f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} // End anonymous namespace 49f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 50f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarchar OptimizeReturned::ID = 0; 51f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarFunctionPass *llvm::createWebAssemblyOptimizeReturned() { 52f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return new OptimizeReturned(); 53f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 54f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 55f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid OptimizeReturned::visitCallSite(CallSite CS) { 56f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (unsigned i = 0, e = CS.getNumArgOperands(); i < e; ++i) 57f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (CS.paramHasAttr(1 + i, Attribute::Returned)) { 58f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Instruction *Inst = CS.getInstruction(); 59f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Value *Arg = CS.getArgOperand(i); 60f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Ignore constants, globals, undef, etc. 61f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (isa<Constant>(Arg)) 62f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar continue; 63f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Like replaceDominatedUsesWith but using Instruction/Use dominance. 64f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto UI = Arg->use_begin(), UE = Arg->use_end(); UI != UE;) { 65f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Use &U = *UI++; 66f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (DT->dominates(Inst, U)) 67f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar U.set(Inst); 68f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 69f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 70f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 71f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 72f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool OptimizeReturned::runOnFunction(Function &F) { 73f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 74f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar visit(F); 75f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 76f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 77