void codegenContiguous(Value* inbuf, Value* incount, Value* outbuf, Datatype *basetype, int inptr_inc, int outptr_inc, int count, bool pack) { Function* TheFunction = Builder.GetInsertBlock()->getParent(); // Loop BasicBlock* PreheaderBB = Builder.GetInsertBlock(); BasicBlock* LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction); Builder.CreateBr(LoopBB); Builder.SetInsertPoint(LoopBB); // Induction var phi nodes PHINode *out = Builder.CreatePHI(LLVM_INT8PTR, 2, "out"); out->addIncoming(outbuf, PreheaderBB); PHINode *in= Builder.CreatePHI(LLVM_INT8PTR, 2, "in"); in->addIncoming(inbuf, PreheaderBB); PHINode *i = Builder.CreatePHI(LLVM_INT32, 2, "i"); i->addIncoming(constNode(0), PreheaderBB); // Basetype Code Generation if (pack) basetype->packCodegen(in, constNode(count), out); else basetype->unpackCodegen(in, constNode(count), out); // Increment the out ptr by outptr_inc Value* out_bytes_to_stride = constNode((long) outptr_inc); Value* out_addr_cvi = Builder.CreatePtrToInt(out, LLVM_INT64); Value* out_addr = Builder.CreateAdd(out_addr_cvi, out_bytes_to_stride); Value* nextout = Builder.CreateIntToPtr(out_addr, LLVM_INT8PTR); // Increment the in ptr by inptr_inc Value* in_bytes_to_stride = constNode((long) inptr_inc); Value* in_addr_cvi = Builder.CreatePtrToInt(in, LLVM_INT64); Value* in_addr = Builder.CreateAdd(in_addr_cvi, in_bytes_to_stride); Value* nextin = Builder.CreateIntToPtr(in_addr, LLVM_INT8PTR); // Increment outer loop index Value* nexti = Builder.CreateAdd(i, constNode(1), "nexti"); Value* EndCond_outer = Builder.CreateICmpEQ(nexti, incount, "loopcond"); // Create and branch to the outer loop postamble BasicBlock *LoopEndBB = Builder.GetInsertBlock(); BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction); Builder.CreateCondBr(EndCond_outer, AfterBB, LoopBB); Builder.SetInsertPoint(AfterBB); // Add backedges for the outer loop induction variable out->addIncoming(nextout, LoopEndBB); in->addIncoming(nextin, LoopEndBB); i->addIncoming(nexti, LoopEndBB); }
osg::ref_ptr<const BulletShape> BulletShapeManager::getShape(const std::string &name) { std::string normalized = name; mVFS->normalizeFilename(normalized); osg::ref_ptr<BulletShape> shape; osg::ref_ptr<osg::Object> obj = mCache->getRefFromObjectCache(normalized); if (obj) shape = osg::ref_ptr<BulletShape>(static_cast<BulletShape*>(obj.get())); else { size_t extPos = normalized.find_last_of('.'); std::string ext; if (extPos != std::string::npos && extPos+1 < normalized.size()) ext = normalized.substr(extPos+1); if (ext == "nif") { NifBullet::BulletNifLoader loader; shape = loader.load(mNifFileManager->get(normalized)); } else { // TODO: support .bullet shape files osg::ref_ptr<const osg::Node> constNode (mSceneManager->getTemplate(normalized)); osg::ref_ptr<osg::Node> node (const_cast<osg::Node*>(constNode.get())); // const-trickery required because there is no const version of NodeVisitor NodeToShapeVisitor visitor; node->accept(visitor); shape = visitor.getShape(); if (!shape) { mCache->addEntryToObjectCache(normalized, NULL); return osg::ref_ptr<BulletShape>(); } } mCache->addEntryToObjectCache(normalized, shape); } return shape; }