[llvm-commits] [parallel] CVS: llvm/lib/Transforms/Parallel/Makefile ParallelCallsToThreads.cpp

Misha Brukman brukman at cs.uiuc.edu
Fri Apr 16 12:28:01 PDT 2004


Changes in directory llvm/lib/Transforms/Parallel:

Makefile added (r1.1.2.1)
ParallelCallsToThreads.cpp added (r1.1.2.1)

---
Log message:

First cut at converting calls in parallel regions to thread-based calls.


---
Diffs of the changes:  (+158 -0)

Index: llvm/lib/Transforms/Parallel/Makefile
diff -c /dev/null llvm/lib/Transforms/Parallel/Makefile:1.1.2.1
*** /dev/null	Fri Apr 16 12:28:08 2004
--- llvm/lib/Transforms/Parallel/Makefile	Fri Apr 16 12:27:58 2004
***************
*** 0 ****
--- 1,16 ----
+ ##===- lib/Transforms/Parallel/Makefile --------------------*- Makefile -*-===##
+ # 
+ #                     The LLVM Compiler Infrastructure
+ #
+ # This file was developed by the LLVM research group and is distributed under
+ # the University of Illinois Open Source License. See LICENSE.TXT for details.
+ # 
+ ##===----------------------------------------------------------------------===##
+ LEVEL = ../../..
+ PARALLEL_DIRS = 
+ LIBRARYNAME = parallel
+ BUILD_ARCHIVE = 1
+ SHARED_LIBRARY = 1
+ 
+ include $(LEVEL)/Makefile.common
+ 


Index: llvm/lib/Transforms/Parallel/ParallelCallsToThreads.cpp
diff -c /dev/null llvm/lib/Transforms/Parallel/ParallelCallsToThreads.cpp:1.1.2.1
*** /dev/null	Fri Apr 16 12:28:08 2004
--- llvm/lib/Transforms/Parallel/ParallelCallsToThreads.cpp	Fri Apr 16 12:27:58 2004
***************
*** 0 ****
--- 1,142 ----
+ //===- PCallToThreads.cpp - Convert parallel calls to pthreads ------------===//
+ // 
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ // 
+ //===----------------------------------------------------------------------===//
+ //
+ // Convert parallel function calls to threaded code.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "llvm/DerivedTypes.h"
+ #include "llvm/Module.h"
+ #include "llvm/iOther.h"
+ #include "llvm/iTerminators.h"
+ #include "llvm/Pass.h"
+ #include "llvm/Type.h"
+ #include "llvm/Analysis/ParallelInfo.h"
+ #include <vector>
+ using namespace llvm;
+ 
+ namespace {
+ 
+   /// PCallToThreads - 
+   ///
+   /// FIXME: This should be a Pass, but Passes currently cannot require
+   /// FunctionPasses.
+   ///
+   struct PCallToThreads : public FunctionPass {
+     Type *startTy;
+ 
+   public:
+     PCallToThreads() {
+       // void*(*start_routine)(void *) is the goal type
+       std::vector<const Type*> ArgTypes;
+       Type *VoidPtr = PointerType::get(Type::SByteTy);
+       ArgTypes.push_back(VoidPtr);
+       FunctionType *FT = FunctionType::get(VoidPtr, ArgTypes, false);
+       startTy = PointerType::get(FT);
+     }
+ 
+     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+       AU.addRequired<ParallelInfo>();
+     }
+     
+     bool runOnFunction(Function &F);
+ 
+   private:
+     Function* getFuncThreadStart(Module &M);
+     Function* getFuncThreadJoin(Module &M);
+   };
+ 
+   RegisterOpt<PCallToThreads>
+   X("pcall-thread", "Convert parallel calls to thread-based code");
+ 
+ } // End anonymous namespace
+ 
+ /// runOnFunction - 
+ ///
+ bool PCallToThreads::runOnFunction(Function &F) {
+   bool Changed = false;
+   ParallelInfo &PI = getAnalysis<ParallelInfo>();
+ 
+   // Convert parallel calls to pthread_create() invocations
+   for (ParallelInfo::iterator i = PI.begin(), e = PI.end(); i != e; ++i) {
+     ParallelSeq *PS = *i;
+     std::vector<Value*> JoinValues;
+     for (ParallelSeq::region_iterator r = PS->region_begin(),
+            re = PS->region_end(); r != re; ++r) {
+       ParallelRegion *PR = *r;
+       std::vector<BasicBlock*> RegionBlocks(PR->begin(), PR->end());
+ 
+       // Ensure that there is only one block in this region
+       assert(RegionBlocks.size() == 1 && "Parallel region has > 1 BB");
+ 
+       // Within the single block, the only code that should be there is a call
+       // and an unconditional branch to the join point
+       BasicBlock* BB = RegionBlocks[0];
+       BasicBlock::iterator Instrs = BB->begin();
+       CallInst *OldCall = dyn_cast<CallInst>(Instrs);
+       assert(OldCall && "First instr is not a call!");
+       
+       // Replace call with __llvm_thread_create
+       Function *ThCreate = getFuncThreadStart(*F.getParent());
+       assert(OldCall->getNumOperands() == 2 && 
+              "Can only threadify calls with one argument!");
+ 
+       TerminatorInst *TI = BB->getTerminator();
+       CastInst *funcPtr = new CastInst(OldCall->getOperand(0), startTy,
+                                        "cast_ptr", TI);
+       CastInst *funcVal = new CastInst(OldCall->getOperand(1),
+                                        PointerType::get(Type::SByteTy),
+                                        "cast_val", TI);
+       std::vector<Value*> Args;
+       Args.push_back(funcPtr);
+       Args.push_back(funcVal);
+       CallInst *ThCreateCall = new CallInst(ThCreate, Args, "threadCall", TI);
+ 
+       OldCall->getParent()->getInstList().erase(OldCall);
+ 
+       Changed = true;
+     }
+ 
+     // Convert llvm.join() intrinsic to __llvm_thread_join() calls
+     // Get join function call position/bb
+     ParaBrInst *Pbr = dyn_cast<ParaBrInst>(PS->getHeader()->getTerminator());
+     assert(Pbr && "Terminator of parallel sequence header is not a Pbr!");
+     
+     std::vector<User*> Users(Pbr->use_begin(), Pbr->use_end());
+     assert(Users.size() == 1 && "Must have unique user of Pbr");
+     CallInst *JoinCall = cast<CallInst>(Users[0]);
+     assert(JoinCall && "Pbr result used in something other than call!");
+     
+     Function *ThJoin = getFuncThreadJoin(*F.getParent());
+     for (std::vector<Value*>::iterator i = JoinValues.begin(), 
+            e = JoinValues.end(); i != e; ++i)
+       CallInst *Join = new CallInst(ThJoin, *i, "join", JoinCall);
+ 
+     if (JoinValues.size() > 0)
+       JoinCall->getParent()->getInstList().erase(JoinCall);
+   }
+ 
+   return Changed;
+ }
+ 
+ /// getFuncThreadStart -
+ ///
+ Function* PCallToThreads::getFuncThreadStart(Module &M) {
+   // int __llvm_thread_create(void*(*)(void*), void*);
+   return M.getOrInsertFunction("__llvm_thread_start", Type::IntTy,
+                                startTy, PointerType::get(Type::SByteTy), 0);
+ }
+ 
+ /// getFuncThreadJoin -
+ ///
+ Function* PCallToThreads::getFuncThreadJoin(Module &M) {
+   // void __llvm_thread_join(int);
+   return M.getOrInsertFunction("__llvm_thread_join", Type::VoidTy, Type::IntTy, 
+                                0);
+ }





More information about the llvm-commits mailing list