diff --git a/ProfilerInformation.cpp b/ProfilerInformation.cpp
index f8e7b7e28880f9235b6edc6a6f42e89806be0cda..70055afbed345d0a5c62d380666cc19362a40074 100644
--- a/ProfilerInformation.cpp
+++ b/ProfilerInformation.cpp
@@ -188,6 +188,10 @@ ProfilerInformation::ProfilerInformation(const char* fn, SMPProgram *CurrProg)
 			/* profiler generated information */
 			addProfileInformation(addr, 0, 0, atoll(scope));
 		}
+		else if (strcmp(type, "BLOCK") == 0)
+		{
+			;  // not processing BLOCK profiling annotation yet
+		}
 		else
 		{
 			msg("ERROR: Unknown annotation type '%s' near line %d\n", type, line);
diff --git a/SMPBasicBlock.h b/SMPBasicBlock.h
index 712901c90da78dbf95092285fd0eac2a221665b2..9d714da5a289dbce1b46500d0d3c47b730228565 100644
--- a/SMPBasicBlock.h
+++ b/SMPBasicBlock.h
@@ -84,6 +84,8 @@ public:
 	inline void SetNumber(int Num) { BlockNum = Num; };
 	void LinkToPred(list<SMPBasicBlock>::iterator Predecessor);
 	void LinkToSucc(list<SMPBasicBlock>::iterator Successor);
+	inline void AddLiveIn(op_t LiveOp) { LiveInSet.insert(LiveOp); return; };
+	inline void AddLiveOut(op_t LiveOp) { LiveOutSet.insert(LiveOp); return; };
 	inline void AddVarKill(op_t KillOp) { KillSet.insert(KillOp); return; };
 	bool ErasePhi(op_t OldOp); // erase() from phi function list
 	void ErasePred(ea_t FirstAddr); // erase() block starting at FirstAddr from Preds list
diff --git a/SMPFunction.cpp b/SMPFunction.cpp
index 6bd9e54d3c918c51816cbae54977c11c4137f82c..ec052417fe71a1e824be418998c7ebc68096c4a6 100644
--- a/SMPFunction.cpp
+++ b/SMPFunction.cpp
@@ -49,6 +49,7 @@
 #define SMP_DEBUG_UNINITIALIZED_SSA_NAMES 1
 #define SMP_WARN_UNUSED_DEFS 0
 #define SMP_DEBUG_SWITCH_TABLE_INFO 0
+#define SMP_OPTIMIZE_BLOCK_PROFILING 0
 
 // Compute LVA/SSA or not? Turn it off for NICECAP demo on 31-JAN-2008
 #define SMP_COMPUTE_LVA_SSA 1
@@ -144,6 +145,9 @@ SMPFunction::SMPFunction(func_t *Info, SMPProgram* pgm) {
 	this->SSAStack.clear();
 	this->LocalVarTable.clear();
 	this->StackFrameMap.clear();
+	this->LiveInSet.clear();
+	this->LiveOutSet.clear();
+	this->KillSet.clear();
 
 	this->ReturnRegTypes.clear();
 	this->SavedRegLoc.clear();
@@ -164,6 +168,36 @@ void SMPFunction::ResetProcessedBlocks(void) {
 	return;
 } // end of SMPFunction::ResetProcessedBlocks()
 
+// Return an iterator for the beginning of the LiveInSet. 
+set<op_t, LessOp>::iterator SMPFunction::GetFirstLiveIn(void) {
+	return this->LiveInSet.begin();
+} // end of SMPBasicBlock::GetFirstLiveIn()
+
+// Get termination iterator marker for the LiveIn set, for use by predecessors.
+set<op_t, LessOp>::iterator SMPFunction::GetLastLiveIn(void) {
+	return this->LiveInSet.end();
+}
+
+// Get iterator for the start of the LiveOut set.
+set<op_t, LessOp>::iterator SMPFunction::GetFirstLiveOut(void) {
+	return this->LiveOutSet.begin();
+}
+
+// Get termination iterator marker for the LiveOut set.
+set<op_t, LessOp>::iterator SMPFunction::GetLastLiveOut(void) {
+	return this->LiveOutSet.end();
+}
+
+// Get iterator for the start of the VarKill set.
+set<op_t, LessOp>::iterator SMPFunction::GetFirstVarKill(void) {
+	return this->KillSet.begin();
+}
+
+// Get termination iterator marker for the VarKill set.
+set<op_t, LessOp>::iterator SMPFunction::GetLastVarKill(void) {
+	return this->KillSet.end();
+}
+
 // Add a caller to the list of all callers of this function.
 void SMPFunction::AddCallSource(ea_t addr) {
 	// Convert call instruction address to beginning address of the caller.
@@ -2588,8 +2622,9 @@ void SMPFunction::LiveVariableAnalysis(void) {
 		++UpExposedIter) {
 			// Add DEF with SSANum of 0.
 			MarkerInst->AddDef(*UpExposedIter, UNINIT, 0);
-			// Add to the VarKill set.
+			// Add to the VarKill and LiveIn sets.
 			this->Blocks.begin()->AddVarKill(*UpExposedIter);
+			this->Blocks.begin()->AddLiveIn(*UpExposedIter);
 	}
 	for (LiveOutIter = this->Blocks.begin()->GetFirstLiveOut();
 		LiveOutIter != this->Blocks.begin()->GetLastLiveOut();
@@ -2597,8 +2632,9 @@ void SMPFunction::LiveVariableAnalysis(void) {
 			if (!(this->Blocks.begin()->IsVarKill(*LiveOutIter))) {
 				// Add DEF with SSANum of 0.
 				MarkerInst->AddDef(*LiveOutIter, UNINIT, 0);
-				// Add to the VarKill set.
+				// Add to the VarKill and LiveIn sets.
 				this->Blocks.begin()->AddVarKill(*LiveOutIter);
+				this->Blocks.begin()->AddLiveIn(*LiveOutIter);
 			}
 	}
 #endif
@@ -3859,11 +3895,13 @@ void SMPFunction::EmitAnnotations(FILE *AnnotFile) {
 	for (CurrBlock = this->Blocks.begin(); CurrBlock != this->Blocks.end(); ++CurrBlock) {
 		if (CurrBlock->MaybeAliasedWrite()) {
 			++(this->UnsafeBlocks);
+#if SMP_OPTIMIZE_BLOCK_PROFILING
 			list<list<SMPInstr>::iterator>::iterator CurrInst;
 			CurrInst = CurrBlock->GetFirstInstr();
 			ea_t addr = (*CurrInst)->GetAddr();
 			qfprintf(AnnotFile,	"%10x %6d BLOCK PROFILECOUNT %s\n", addr,
 				(*CurrInst)->GetCmd().size, (*CurrInst)->GetDisasm());
+#endif
 		}
 		else {
 			++(this->SafeBlocks);
diff --git a/SMPFunction.h b/SMPFunction.h
index e875f8ef380ed1aac91507df144c5c60a7717501..51bef3787018b381e4f04475d67221eb7eb06e16 100644
--- a/SMPFunction.h
+++ b/SMPFunction.h
@@ -74,6 +74,12 @@ public:
 	inline set<op_t, LessOp>::iterator GetLastGlobalName(void) { return GlobalNames.end(); };
 	inline size_t NumGlobalNames(void) { return GlobalNames.size(); };
 	inline set<op_t, LessOp>::iterator FindGlobalName(op_t SearchOp) { return GlobalNames.find(SearchOp); };
+	set<op_t, LessOp>::iterator GetFirstLiveIn(void); // LiveInSet.begin()
+	set<op_t, LessOp>::iterator GetLastLiveIn(void); // LiveInSet.end()
+	set<op_t, LessOp>::iterator GetFirstLiveOut(void); // LiveOutSet.begin()
+	set<op_t, LessOp>::iterator GetLastLiveOut(void); // LiveOutSet.end()
+	set<op_t, LessOp>::iterator GetFirstVarKill(void); // KillSet.begin()
+	set<op_t, LessOp>::iterator GetLastVarKill(void); // KillSet.end()
 	inline FuncType GetReturnAddressStatus(void) const { return ReturnAddrStatus;}
 	inline const ea_t GetStartAddr() const { return FuncInfo.startEA; }; // exposing the start address of the function. Used in RecurseAndMark
 	inline const vector<ea_t> GetCallTargets() const { return AllCallTargets; };
@@ -113,12 +119,22 @@ public:
 	inline bool WritesAboveReturnAddress(void) const { return WritesAboveRA; };
 	inline bool IsGlobalName(op_t RefOp) const { return (GlobalNames.end() != GlobalNames.find(RefOp)); };
 	inline bool UsesFramePointer(void) const { return UseFP; };
+	inline bool IsLiveIn(op_t CurrOp) const {
+		return (LiveInSet.end() != LiveInSet.find(CurrOp));
+	}
+	inline bool IsLiveOut(op_t CurrOp) const {
+		return (LiveOutSet.end() != LiveOutSet.find(CurrOp));
+	}
+	inline bool IsVarKill(op_t CurrOp) const {
+		return (KillSet.end() != KillSet.find(CurrOp));
+	}
 
 	// Printing methods
 	void Dump(void); // debug dump
 
 	// Analysis methods
 	void ResetProcessedBlocks(void); // Set Processed flag to false in all blocks
+	bool ComputeGlobalSets(void); // return true if LiveIn, LiveOut, Kill sets change
 	void Analyze(void);  // Analyze all instructions in function
 	void EmitAnnotations(FILE *AnnotFile);
 	void RPONumberBlocks(void);
@@ -199,6 +215,11 @@ private:
 	vector<int> SavedRegLoc; // indexed by reg #; offset from return address of callee-saved reg
 	vector<SMPOperandType> ReturnRegTypes; // indexed by reg #; inferred types upon return
 
+		// Four sets used in live variable analysis
+	set<op_t, LessOp> KillSet;   // registers killed in this function
+	set<op_t, LessOp> LiveOutSet; // Live-Out registers in this function
+	set<op_t, LessOp> LiveInSet; // registers live in to this function
+
 	// Methods
 	void SetStackFrameInfo(void);
 	ea_t FindAllocPoint(asize_t); // Deal with difficult to find stack frame allocations
diff --git a/SMPProgram.cpp b/SMPProgram.cpp
index 0cd03075416bd1944b45bb7c4bcf68a2923ed595..ae541f73493c86f9c0bcd161193d18419a14aae3 100644
--- a/SMPProgram.cpp
+++ b/SMPProgram.cpp
@@ -337,7 +337,11 @@ void SMPProgram::Analyze(ProfilerInformation *pi) {
 		} // end if SEG_CODE segment
 	} // end for all segments
 
-	map<ea_t, SMPFunction *>::iterator MapIter;
+#if 0
+	this->ComputeGlobalSets();
+#endif
+
+	map<ea_t, SMPFunction*>::iterator MapIter;
 	for (MapIter = this->FuncMap.begin(); MapIter != this->FuncMap.end(); ++MapIter) {
 		CurrFunc = MapIter->second;
 		if (NULL == CurrFunc) {
diff --git a/SMPProgram.h b/SMPProgram.h
index 8162c098f3c05c086d064e2956ff1a24b74fc6b2..b362b3794968e1a7b13d3fbcd2ff71d20ecf9eb5 100644
--- a/SMPProgram.h
+++ b/SMPProgram.h
@@ -106,6 +106,7 @@ private:
 	// Methods
 	void InitStaticDataTable(void); // Gather info about global static data locations
 	void ComputeGlobalFieldOffsets(struct GlobalVar &CurrGlobal);
+	void ComputeGlobalSets(void); // LiveIn, LiveOut, VarKill for each func
 	FuncType RecurseAndMarkRetAdd(SMPFunction *);
 }; // end class SMPProgram