123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- ///////////////////////////////////////////////////////////////////////////////
- // //
- // HLPreprocess.cpp //
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- // This file is distributed under the University of Illinois Open Source //
- // License. See LICENSE.TXT for details. //
- // //
- // Preprocess HLModule after inline. //
- // //
- ///////////////////////////////////////////////////////////////////////////////
- #include "llvm/IR/Function.h"
- #include "llvm/IR/Module.h"
- #include "llvm/IR/IRBuilder.h"
- #include "llvm/IR/Intrinsics.h"
- #include "dxc/HLSL/DxilGenerationPass.h"
- using namespace llvm;
- ///////////////////////////////////////////////////////////////////////////////
- // HLPreprocess.
- // Inliner will create stacksave stackstore if there are allocas inside block
- // other than entry block. HLPreprocess will remove stacksave and stackstore and
- // put all allocas inside entry block.
- //
- namespace {
- class HLPreprocess : public ModulePass {
- public:
- static char ID; // Pass identification, replacement for typeid
- explicit HLPreprocess() : ModulePass(ID) {}
- const char *getPassName() const override {
- return "Preprocess HLModule after inline";
- }
- bool runOnModule(Module &M) override {
- bool bUpdated = false;
- // Remove stacksave and stackstore.
- // Get the two intrinsics we care about.
- Function *StackSave = Intrinsic::getDeclaration(&M, Intrinsic::stacksave);
- Function *StackRestore =
- Intrinsic::getDeclaration(&M, Intrinsic::stackrestore);
- // If has user, remove user first.
- if (!StackSave->user_empty() || !StackRestore->user_empty()) {
- for (auto it = StackRestore->user_begin();
- it != StackRestore->user_end();) {
- Instruction *I = cast<Instruction>(*(it++));
- I->eraseFromParent();
- }
- for (auto it = StackSave->user_begin(); it != StackSave->user_end(); ) {
- Instruction *I = cast<Instruction>(*(it++));
- I->eraseFromParent();
- }
- bUpdated = true;
- }
- StackSave->eraseFromParent();
- StackRestore->eraseFromParent();
- // If stacksave/store is present, it means alloca not in the
- // entry block. However, there could be other cases where allocas
- // could be present in the non-entry blocks.
- // Therefore, always go through all non-entry blocks and
- // make sure all allocas are moved to the entry block.
- for (Function &F : M.functions()) {
- bUpdated |= MoveAllocasToEntryBlock(&F);
- }
- return bUpdated;
- }
- private:
- bool MoveAllocasToEntryBlock(Function *F);
- };
- char HLPreprocess::ID = 0;
- // Make sure all allocas are in entry block.
- bool HLPreprocess::MoveAllocasToEntryBlock(Function *F) {
- bool changed = false;
- if (F->getBasicBlockList().size() < 2)
- return changed;
- BasicBlock &Entry = F->getEntryBlock();
- IRBuilder<> Builder(Entry.getFirstInsertionPt());
- for (auto bb = F->begin(); bb != F->end(); bb++) {
- BasicBlock *BB = bb;
- if (BB == &Entry)
- continue;
- for (auto it = BB->begin(); it != BB->end();) {
- Instruction *I = (it++);
- if (isa<AllocaInst>(I)) {
- I->removeFromParent();
- Builder.Insert(I);
- changed = true;
- }
- }
- }
- return changed;
- }
- } // namespace
- ModulePass *llvm::createHLPreprocessPass() { return new HLPreprocess(); }
- INITIALIZE_PASS(HLPreprocess, "hl-preprocess",
- "Preprocess HLModule after inline", false, false)
|