socsvn commit: r273535 - soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw

dpl at FreeBSD.org dpl at FreeBSD.org
Wed Sep 3 10:32:21 UTC 2014


Author: dpl
Date: Wed Sep  3 10:32:20 2014
New Revision: 273535
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=273535

Log:
  No assertions, cleaned the code.

Modified:
  soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc

Modified: soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc
==============================================================================
--- soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc	Wed Sep  3 10:22:49 2014	(r273534)
+++ soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc	Wed Sep  3 10:32:20 2014	(r273535)
@@ -62,13 +62,10 @@
 	PointerType *Int8PtrTy;
 
 	// Basic blocks used
-	BasicBlock *Entry, *End;
-	BasicBlock *Pullup_failed;
-	BasicBlock *Check_tag;
-	BasicBlock *Outer_for_prologue;
-	BasicBlock *Inner_for_prologue;
-	BasicBlock *Outer_for_epilogue;
-	BasicBlock *Inner_for_epilogue;
+	BasicBlock *Entry;
+	BasicBlock *End;
+	BasicBlock *PullupFailed;
+	BasicBlock *CheckTag;
 
 	// JIT Compiled Vars
 	// These are the function arguments.
@@ -172,15 +169,15 @@
 	Module *
 	loadBitcode(std::string name)
 	{
-		auto buffer = MemoryBuffer::getFile(name);
-		if (buffer.getError()){
-			std::cerr << "Failed to open bitcode: " << buffer.getError() << "\n";
+		auto buff = MemoryBuffer::getFile(name);
+		if (buff.getError()){
+			std::cerr << "Failed to open bitcode: " << buff.getError() << "\n";
 			return (NULL);
 		}
 
-		auto modptr = parseBitcodeFile(buffer.get().get(), Con);
+		auto modptr = parseBitcodeFile(buff.get().get(), Con);
 		if ((modptr.getError())){
-			std::cerr << "Failed to parse bitcode: " << buffer.getError() << "\n";
+			std::cerr << "Failed to parse bitcode: " << buff.getError() << "\n";
 			return (NULL);
 		}
 		return (modptr.get());
@@ -397,9 +394,10 @@
 			Is_ipv6, Hlen, Proto, Icmp6_type, Ip6f_mf, Offset, UlpL});
 
 		Value *Cond = Irb.CreateICmpEQ(InspectPktCall, ConstantInt::get(Int32Ty, 1));
-		Irb.CreateCondBr(Cond, Pullup_failed, Check_tag);
+		Irb.CreateCondBr(Cond, PullupFailed, CheckTag);
 	}
 
+	// This is equivalent to the pullup_failed tag.
 	void
 	emit_pullup_failed()
 	{
@@ -421,7 +419,7 @@
 		Is_verbose = mod->getGlobalVariable("fw_verbose");
 		Str = Irb.CreateGlobalString("ipfw: pullup failed\n");
 
-		Irb.SetInsertPoint(Pullup_failed);
+		Irb.SetInsertPoint(PullupFailed);
 
 		// if (V_fw_verbose)
 		Value *Is_verboseL = Irb.CreateLoad(Is_verbose); 
@@ -449,7 +447,7 @@
 
 		Value *Comp;
 
-		Irb.SetInsertPoint(Check_tag);
+		Irb.SetInsertPoint(CheckTag);
 
 		// if (args->rule.slot) {
 		// 	/*
@@ -510,6 +508,111 @@
 		Irb.CreateBr(rules.front());
 	}
 
+	public:
+	ipfwJIT(int rulesnumber): Irb(Con)
+	{
+		// Create the module and load the code.
+		mod = loadBitcode("rules.bc");
+
+		Func = mod->getFunction("ipfw_chk_jit");
+		Func->setLinkage(GlobalValue::ExternalLinkage);
+		// Create static BasicBlocks.
+		// The entry basic block contains all the initialization 
+		// and allocation of resources, and a basic check done 
+		// before start emmiting the rules code.
+		Entry = BasicBlock::Create(Con, "Entry", Func);
+		End = BasicBlock::Create(Con, "End", Func);
+		CheckTag = BasicBlock::Create(Con, "CheckTag", Func);
+		PullupFailed = BasicBlock::Create(Con, "PullupFailed", Func);
+
+
+		// Get struct types, and store vars
+		setEnv();
+
+		// Start compilation
+		allocaAndInit();
+
+		// Initialize the vector.
+		rules = std::vector<BasicBlock *>(rulesnumber);
+		for (auto &i: rules){
+			i = BasicBlock::Create(Con, "rule", Func);
+		}
+
+		emit_check_tag();
+		emit_pullup_failed();
+	}
+	~ipfwJIT()
+	{
+		if (mod)
+			delete mod;
+	}
+
+	funcptr
+	compile()
+	{
+		InitializeNativeTarget();
+		LLVMLinkInJIT();
+
+// 		//Optimise
+// 		PassManagerBuilder PMBuilder;
+// 		PMBuilder.OptLevel = 1;
+// 		PMBuilder.Inliner = createFunctionInliningPass(275);
+
+// 		// Function passes
+// 		FunctionPassManager *PerFunctionPasses = new FunctionPassManager(mod);
+// 		PMBuilder.populateFunctionPassManager(*PerFunctionPasses);
+// 		PerFunctionPasses->run(*Func);
+// 		PerFunctionPasses->doFinalization();
+// 		delete PerFunctionPasses;
+
+// 		printf("Done optimizing Function\n");
+
+// 		// Module passes
+// 		PassManager *PerModulePasses = new PassManager();
+// 		PMBuilder.populateModulePassManager(*PerModulePasses);
+// 		PerModulePasses->run(*mod);
+// 		delete PerModulePasses;
+
+// 		printf("Done optimizing Module\n");
+
+		// // We don't need it anymore.
+		// Function *vf = mod->getFunction("voidfunction");
+		// vf->eraseFromParent();
+		// printf("Done erasing voidfunction\n");
+
+		//Compile
+		std::string comperr = "Compilation error\n";
+		std::string errstr;
+
+		EngineBuilder EB = EngineBuilder(std::unique_ptr<Module>(mod));
+		EB.setEngineKind(EngineKind::Kind::JIT);
+		EB.setUseMCJIT(true);
+		EB.setErrorStr(&comperr);
+		EB.setVerifyModules(true);
+		EB.setOptLevel(CodeGenOpt::Level::None);
+
+		ExecutionEngine *EE = EB.create();
+		if (!EE) {
+			fprintf(stderr, "Error: %s\n", errstr.c_str());
+			exit(1);
+		}
+
+		//mod->dump();
+		//InspectPkt->dump();
+		mod->getFunction("m_freem")->dump();
+
+		printf("FuncPtr: %p\n", (void *)EE->getPointerToFunction(Func));
+		//printf("FuncPtr: %p\n", (void *)EE->getFunctionAddress("ipfw_chk_jit"));
+		err(1,"null");
+		return (funcptr)EE->getFunctionAddress("ipfw_chk_jit");
+	}
+
+	void
+	end_rule()
+	{
+		rulenumber++;
+	}
+
 	void
 	emit_outer_for_prologue()
 	{
@@ -528,7 +631,9 @@
 		// 	continue;
 		// skip_or = 0;
 
-		Irb.SetInsertPoint(Outer_for_prologue);
+		// Write at the rule.
+		Irb.SetInsertPoint(rules[rulenumber]);
+
 		// uInt32_t tablearg = 0;
 		Irb.CreateStore(ConstantInt::get(Int32Ty, 0), Tablearg);
 
@@ -557,8 +662,6 @@
 		// skip_or = 0;
 		Irb.SetInsertPoint(jf);
 		Irb.CreateStore(ConstantInt::get(Int32Ty, 0), SkipOr);
-
-		Irb.CreateBr(Inner_for_prologue);
 	}
 
 	void
@@ -583,7 +686,6 @@
 		// 		continue;
 		// 	}
 		// 	match = 0; /* set to 1 if we succeed */
-		Irb.SetInsertPoint(Inner_for_prologue);
 
 		// l = f->cmd_len;
 		Value *FL = Irb.CreateLoad(F);
@@ -632,10 +734,9 @@
 		Irb.SetInsertPoint(firstf);
 		// match = 0;
 		Irb.CreateStore(ConstantInt::get(Int32Ty, 0), Match);
-
-		Irb.CreateBr(Inner_for_epilogue);
 	}
 
+
 	// We get here ar the end of switch() on opcodes.
 	void
 	emit_inner_for_epilogue()
@@ -647,6 +748,7 @@
 		BasicBlock *matchzero = BasicBlock::Create(Con, "matchzero", Func);
 		BasicBlock *matchnotzero = BasicBlock::Create(Con, "matchnotzero", Func);
 		BasicBlock *is_or = BasicBlock::Create(Con, "is_or", Func);
+		BasicBlock *Continue = BasicBlock::Create(Con, "Continue", Func);
 
 		Value *Comp, *AndOp;
 
@@ -657,7 +759,7 @@
 		Value *Sub = Irb.CreateNSWSub(LL, CmdLenL);
 		Irb.CreateStore(Sub, L);
 
-		// TODO -- Should ensure correctness of code.
+		// TODO - Should ensure correctness of code.
 		// ipfw_insn *cmd; Add to pointer.
 		// Note: Since LLVM can't add to a ptr, we can use GEP with casted Ptr.
 		// cmd += cmdlen;
@@ -676,8 +778,6 @@
 		// 		break;		/* try next rule    */
 		// }
 
-		Irb.SetInsertPoint(Inner_for_epilogue);
-
 		// if (cmd->len & F_NOT)
 		Value *Len = Irb.CreateStructGEP(CmdL, 1);
 		Value *LenL = Irb.CreateLoad(Len);
@@ -702,6 +802,7 @@
 
 		Irb.SetInsertPoint(sec_cond);
 		// if (match)
+		MatchL = Irb.CreateLoad(Match);
 		Comp = Irb.CreateICmpNE(MatchL, ConstantInt::get(Int32Ty, 0));
 		Irb.CreateCondBr(Comp, matchnotzero, matchzero);
 
@@ -709,28 +810,29 @@
 		// if (cmd->len & F_OR)
 		AndOp = Irb.CreateAnd(LenL, ConstantInt::get(Int8Ty, F_OR));
 		Comp = Irb.CreateICmpNE(AndOp, ConstantInt::get(Int8Ty, 0));
-		Irb.CreateCondBr(Comp, is_or, Outer_for_epilogue);
+		Irb.CreateCondBr(Comp, is_or, Continue);
 
 		Irb.SetInsertPoint(is_or);
 		// skip_or = 1;
 		Irb.CreateStore(ConstantInt::get(Int32Ty, 1), SkipOr);
-		Irb.CreateBr(Outer_for_epilogue);
+		Irb.CreateBr(Continue);
 
 		Irb.SetInsertPoint(matchzero);
 		// if (!(cmd->len & F_OR)) /* not an OR block, */
 		//     break;
 		AndOp = Irb.CreateAnd(LenL, ConstantInt::get(Int8Ty, F_OR));
 		Comp = Irb.CreateICmpEQ(AndOp, ConstantInt::get(Int8Ty, 0));
-		Irb.CreateCondBr(Comp, nextRule(rulenumber+1) /* break */, Outer_for_epilogue);
+		Irb.CreateCondBr(Comp, nextRule(rulenumber+1) /* break */, Continue);
+		
+		Irb.SetInsertPoint(Continue);
 	}
 
+
 	// This code gets executed at the end of inner loop.
 	// In this context, break means goto end, else continue loop.
 	void
 	emit_outer_for_epilogue()
 	{
-		Irb.SetInsertPoint(Outer_for_epilogue);
-
 		// f_pos++, increment of the for loop.
 		Value *FPosL = Irb.CreateLoad(FPos);
 		Value *AddOp = Irb.CreateAdd(FPosL, ConstantInt::get(Int32Ty, 1));
@@ -743,6 +845,7 @@
 		Irb.CreateCondBr(Comp, End, nextRule(rulenumber+1));
 	}
 
+
 	void
 	emit_end()
 	{
@@ -750,7 +853,11 @@
 
 		BasicBlock *Jt = BasicBlock::Create(Con, "jt", Func);
 		BasicBlock *Jf = BasicBlock::Create(Con, "jf", Func);
+		BasicBlock *DoCache = BasicBlock::Create(Con, "cache", Func);
 		BasicBlock *Ret = BasicBlock::Create(Con, "ret", Func);
+	#ifdef __FreeBSD__
+		BasicBlock *CacheNN = BasicBlock::Create(Con, "cachennull", Func);
+	#endif
 		Value *Comp, *AddOp;
 
 		// if (done) {
@@ -816,6 +923,7 @@
 		Value *TimeUptimeL32 = Irb.CreateTrunc(TimeUptimeL, Int32Ty);
 		Value *Timestamp = Irb.CreateStructGEP(RuleL, 10);
 		Irb.CreateStore(TimeUptimeL32, Timestamp);
+		Irb.CreateBr(DoCache);
 
 		Irb.SetInsertPoint(Jf);
 		//	retval = IP_FW_DENY;
@@ -823,166 +931,29 @@
 		Irb.CreateStore(ConstantInt::get(Int32Ty, IP_FW_DENY), Retval);
 		Value *StrFirstElement = Irb.CreateStructGEP(Str, 0);
 		Irb.CreateCall(PrintfFunc, StrFirstElement);
+		Irb.CreateBr(DoCache);
+
+		Irb.SetInsertPoint(DoCache);
 #ifndef __FreeBSD__
-		Irb.CreateBr(ret);
+		Irb.CreateBr(Ret);
 #endif
 
 #ifdef __FreeBSD__
-		{
-			Irb.SetInsertPoint(End);
-			BasicBlock *CacheNN = BasicBlock::Create(Con, "cachennull", Func);
-			// 	if (ucred_cache != NULL)
-			Comp = Irb.CreateICmpNE(Ucred_cache, 
-				ConstantPointerNull::get(UcredPtrTy));
-			Irb.CreateCondBr(Comp, CacheNN, Ret);
+		// 	if (ucred_cache != NULL)
+		Comp = Irb.CreateICmpNE(Ucred_cache, 
+			ConstantPointerNull::get(UcredPtrTy));
+		Irb.CreateCondBr(Comp, CacheNN, Ret);
 
-			Irb.SetInsertPoint(CacheNN);
-			Irb.CreateBr(Ret);
-		}
+		Irb.SetInsertPoint(CacheNN);
+		Irb.CreateBr(Ret);
 #endif
 
+		//Return retval
 		Irb.SetInsertPoint(Ret);
-		Irb.CreateRet(Retval);
+		Value *RetvalL = Irb.CreateLoad(Retval);
+		Irb.CreateRet(RetvalL);
 	}
 
-	public:
-	ipfwJIT(int rulesnumber): Irb(Con)
-	{
-		// Create the module and load the code.
-		mod = loadBitcode("ip_fw_rules.bc");
-
-		Func = mod->getFunction("ipfw_chk_jit");
-		Func->setLinkage(GlobalValue::ExternalLinkage);
-
-		// Initialize the vector.
-		rules = std::vector<BasicBlock *>(rulesnumber);
-		for (auto &i: rules){
-			i = BasicBlock::Create(Con, "rule", Func);
-		}
-
-		// Create static BasicBlocks.
-		// The entry basic block contains all the initialization 
-		// and allocation of resources, and a basic check done 
-		// before start emmiting the rules code.
-		Entry = BasicBlock::Create(Con, "Entry", Func);
-		End = BasicBlock::Create(Con, "End", Func);
-		Check_tag = BasicBlock::Create(Con, "CheckTag", Func);
-		// This is equivalent to the pullup_failed tag.
-		Pullup_failed = BasicBlock::Create(Con, "PullupFailed", Func);
-		//Snippets of code to be executed when iterating through the rules.
-		Outer_for_prologue = BasicBlock::Create(Con, "OuterForPrologue", Func);
-		Inner_for_prologue = BasicBlock::Create(Con, "InnerForPrologue", Func);
-		Inner_for_epilogue = BasicBlock::Create(Con, "InnerForEpilogue", Func);
-		Outer_for_epilogue = BasicBlock::Create(Con, "OuterForEpilogue", Func);
-
-		// Get struct types, and store vars
-		setEnv();
-
-		// Start compilation
-		allocaAndInit();
-		emit_check_tag();
-		emit_pullup_failed();
-
-		// Snippets of code to be used for each iteration.
-		emit_outer_for_prologue();
-		emit_inner_for_prologue();
-		emit_inner_for_epilogue();
-		emit_outer_for_epilogue();
-		emit_end();
-	}
-	~ipfwJIT()
-	{
-		if (mod)
-			delete mod;
-	}
-
-	funcptr
-	compile()
-	{
-		std::string errstr;
-		std::string comperr = "Compilation error\n";
-
-		// Check correctness.
-		verifyFunction(*Func);
-		verifyModule(*mod);
-
-		InitializeNativeTarget();
-		LLVMLinkInJIT();
-
-		//Optimise
-		PassManagerBuilder PMBuilder;
-		PMBuilder.OptLevel = 0;
-		PMBuilder.Inliner = createFunctionInliningPass(275);
-
-		// Function passes
-		FunctionPassManager *PerFunctionPasses = new FunctionPassManager(mod);
-		PMBuilder.populateFunctionPassManager(*PerFunctionPasses);
-		PerFunctionPasses->run(*Func);
-		PerFunctionPasses->doFinalization();
-		delete PerFunctionPasses;
-
-		// Module passes
-		PassManager *PerModulePasses = new PassManager();
-		PMBuilder.populateModulePassManager(*PerModulePasses);
-		//PerModulePasses->run(*mod);
-		delete PerModulePasses;
-
-		// We don't need it anymore.
-		Function *vf = mod->getFunction("voidfunction");
-		vf->eraseFromParent();
-
-		//Compile
-		EngineBuilder EB = EngineBuilder(std::unique_ptr<Module>(mod));
-		EB.setErrorStr(&comperr);
-
-		ExecutionEngine *EE = EB.create();
-		if (!EE) {
-			fprintf(stderr, "Error: %s\n", errstr.c_str());
-			exit(1);
-		}
-
-		printf("FuncPtr: %p\n", (void *)EE->getFunctionAddress("ipfw_chk_jit"));
-		err(1,"null");
-		return (funcptr)EE->getFunctionAddress("ipfw_chk_jit");
-	}
-
-	void
-	end_rule()
-	{
-		rulenumber++;
-	}
-
-	// Also initialized the rules vector.
-	void
-	emit_outer_for_prologue_call()
-	{
-		Irb.SetInsertPoint(rules[rulenumber]);
-		Irb.CreateBr(Outer_for_prologue);
-	}
-
-	void
-	emit_inner_for_prologue_call()
-	{
-		Irb.CreateBr(Inner_for_prologue);
-	}
-
-	void
-	emit_inner_for_epilogue_call()
-	{
-		Irb.CreateBr(Inner_for_epilogue);
-	}
-
-	void
-	emit_outer_for_epilogue_call()
-	{
-		Irb.CreateBr(Outer_for_epilogue);
-	}
-
-	void
-	emit_end_call()
-	{
-		Irb.CreateBr(End);
-	}
 
 	// Rules
 	void
@@ -1069,14 +1040,14 @@
 		f = chain->map[f_pos];
 
 		// Rule start.
-		compiler.emit_outer_for_prologue_call();
+		compiler.emit_outer_for_prologue();
 
 		// For each different command.
 		for (l = f->cmd_len, cmd = f->cmd ; l > 0 ;
 		    l -= cmdlen, cmd += cmdlen) {
 /* check_body: */
 			cmdlen = F_LEN(cmd);
-			compiler.emit_inner_for_prologue_call();
+			compiler.emit_inner_for_prologue();
 			switch (cmd->opcode) {
 			case O_NOP:
 				compiler.emit_nop();
@@ -1458,14 +1429,14 @@
 			default:
 				panic("-- unknown opcode %d\n", cmd->opcode);
 			} /* end of switch() on opcodes */
-			compiler.emit_inner_for_epilogue_call();
+			compiler.emit_inner_for_epilogue();
 		}	/* end of inner loop, scan opcodes */
 		// Rule ends.
-		compiler.emit_outer_for_epilogue_call();
+		compiler.emit_outer_for_epilogue();
 		compiler.end_rule();
 	}		/* end of outer for, scan rules */
 
-	compiler.emit_end_call();
+	compiler.emit_end();
 
 	// Once we're done iterating through the rules, return the pointer.
 	return (compiler.compile());


More information about the svn-soc-all mailing list