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